序列和问题

链接:https://www.nowcoder.com/questionTerminal/46eb436eb6564a62b9f972160e1699c9
来源:牛客网

给出一个正整数N和长度L,找出一段长度大于等于L的连续非负整数,他们的和恰好为N。答案可能有多个,我我们需要找出长度最小的那个。
例如 N = 18 L = 2:
5 + 6 + 7 = 18
3 + 4 + 5 + 6 = 18
都是满足要求的,但是我们输出更短的 5 6 7
输入描述:输入数据包括一行: 两个正整数N(1 ≤ N ≤ 1000000000),L(2 ≤ L ≤ 100)
输出描述:从小到大输出这段连续非负整数,以空格分隔,行末无空格。如果没有这样的序列或者找出的序列长度大于100,则输出No
  • 这道题首先拿到手就需要敏感的观察到这个序列的性质:等差数列,等差数d=1;所以我们利用等差数列的求和性质可以做这道题。直接从[L,100]循环遍历,找到第一个n,就是最短的序列。
import java.util.Scanner;
public class Main{
    public static void main(String args[]){
        Scanner in = new Scanner(System.in);
        while(in.hasNext()){
            int N = in.nextInt();
            int L = in.nextInt();
            //标志位,如果循环结束还没有找到序列就输出No
            boolean flag = false;
            for(int i=L;i<=100;i++){
            //这里就是求等差数列的第一项
                if((2*N-i*i+i) % (2*i) == 0){
                    int a1 = (2*N-i*i+i) / (2*i);
                    if(a1 < 0){
                        continue;
                    }
                    flag = true;
                    //输出
                    for(int j=0;j<i-1;j++){
                        System.out.print(a1 + j + " ");
                    }
                    System.out.print(a1 + i - 1);
                    //直接跳出循环,不用继续再找下去了
                    break;
                }
            }
            if(flag == false){
                System.out.print("No");
            }
        }
    }
}
  • 当然,这道题还是可以用中位数的方法去做,用18来举例说明:
18 = 5 + 6 + 7;可见这里18 = 6 * 3;6是这个序列的中位数,那么也就是说这个序列和÷序列的长度是个整数,(序列长度是奇数)那
么这个序列和一定等于这个序列的中位数*序列长度;
18 = 3 + 4 + 5 + 6;这里18 = 4.5 * 4 = (4 + 5) / 2 * 4;也就是说如果这个序列和÷序列的长度不是整数,(序列长度是偶数),那么这个
序列和一定等于这个序列的2个中位数和÷2*序列长度;
链接:https://www.nowcoder.com/questionTerminal/46eb436eb6564a62b9f972160e1699c9
来源:牛客网
/*
 * 题目需要找出一段长度大于等于L的连续非负整数,使得其和等于N。L要尽可能小。
 * 考虑是连续非负整数,所以其和我们能用中位数来表示,分两种情况:
 * 情况一,长度为奇数的情况:
 *   此时中位数一定是整数,N = 中位数 x L
 * 情况二,长度为偶数的情况:
 *   此时中位数肯定是xx.5的形式,N = xx.5 * L
 * 所以我们从长度L开始枚举,至100为止,分奇偶讨论。
 */
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt(), l = in.nextInt();
        in.close();
        int bg = -1, ed = -1;
        for (int i = l; i <= 100; ++i) {
            // 奇数,中位数一定是整数
            if (i % 2 == 1 && n % i == 0) {
                int mid = n / i;
                bg = mid - (i - 1) / 2;
                ed = mid + (i - 1) / 2;
                if (bg >= 0) // 答案要合法,即需要是非负整数
                    break;
            }
            // 偶数,中位数一定是0.5形式
            if (i % 2 == 0 && (double)n / i - n / i == 0.5f) {
                int mid = n / i;
                bg = mid - i / 2 + 1;
                ed = mid + i / 2;
                if (bg >= 0)
                    break;
            }
        }
        if (bg >= 0) {
            for (int i = bg; i < ed; ++i) {
                System.out.print(i + " ");
            }
            System.out.println(ed);
        }
        else {
            System.out.println("No");
        }
    }
}

猜你喜欢

转载自blog.csdn.net/harryshumxu/article/details/105328515