题目: * 数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一部分的数列,只记得其中个整数。 * 现在给出这N个整数,小明想知道包含这N个整数的最短的等差数列有几项? * 输入描述 * 输入的第一行包含一个整数N * 第二行包含N个整数A1,A2 ··,AN。(注意A1~AN 并不一定是按等差数列中的顺序给出) * 其中,2<N<105,0< Ai< 109 * 思路: 首先他给的测试样例不一定是安装顺序的 所以我们要排序 * 然后这个题的意思其实就等于是填数字,比如他的样例 2 4 6 10 20 * 用后一项减去前一项来得到公差,4-2=2 6-4=2 所以当前公差是2 后续还要继续减 我们保留这个公差 也就是最大公约数 * 最坏的情况公差就是1 那长度就最大 找到最大公约数就可以让长度尽量小 * 在38-43行代码我们就是不断求公差 即最大公约数 * 然后还要特判一下 害怕公差是0 可能存在样例全是一样的情况 比如 1 1 1 这样公差就是零 那么长度就是这个数的本身 * 最后我们输出使用最后一项减去第一项 再除公差+1 就是答案 比如 首项是2 尾项是20 2 加 公差2加到20需要加 9次 还需要加上自己这个2 一共十次 输出10 * 这个题的本质其实就是填数 只不过填的数是所有数的最大公约数 最坏的情况就是公差是1 */ public class 等差数列 {
public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] a = new int[n]; for (int i = 0; i < n; i++) { a[i] = sc.nextInt(); } // 记得排序 免得测试样例不是按照顺序来的 Arrays.sort(a); // 公差 int gcd = a[1] - a[0]; for (int i = 2; i < n; i++) { // 不断求最大公约数 gcd = gcd(gcd, a[i] - a[i - 1]); } // 特判 公差可能是0 比如样例是 1 1 1 if (gcd == 0) System.out.println(n); //项是2 尾项是20 2 加 公差2加到20需要加 9次 还需要加上自己这个2 一共十次 else System.out.println( ( a[n - 1] - a[0] )/ gcd + 1); } // 递归求2个数的最大公约数 static int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
static int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } }