洛谷 P1214 [USACO1.4]等差数列 Arithmetic Progressions
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 P1214 [USACO1.4]等差数列 Arithmetic Progressions相关的知识,希望对你有一定的参考价值。
题目描述
一个等差数列是一个能表示成a, a+b, a+2b,..., a+nb (n=0,1,2,3,...)的数列。
在这个问题中a是一个非负的整数,b是正整数。写一个程序来找出在双平方数集合(双平方数集合是所有能表示成p的平方 + q的平方的数的集合,其中p和q为非负整数)S中长度为n的等差数列。
输入输出格式
输入格式:
第一行: N(3<= N<=25),要找的等差数列的长度。
第二行: M(1<= M<=250),搜索双平方数的上界0 <= p,q <= M。
输出格式:
如果没有找到数列,输出`NONE‘。
如果找到了,输出一行或多行, 每行由二个整数组成:a,b。
这些行应该先按b排序再按a排序。
所求的等差数列将不会多于10,000个。
输入输出样例
5 7
1 4 37 4 2 8 29 8 1 12 5 12 13 12 17 12 5 20 2 24
说明
题目翻译来自NOCOW。
USACO Training Section 1.4
【分析】
因为数列的项数的是确定的,所以只要知道前两个数就可以确定整个数列。
但是需要加点优化,每次先判断一下数列的最后一个数是否大于m*m*2,如果大于的话就说明第二个点太后了,第一个点直接跳到下一个就可以了。
倒着找会快一点,不过这样也足够了。
【代码】
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 struct node { 5 int a, b; 6 }w[10005]; 7 bool cmp(node a, node b) { 8 if (a.b==b.b) 9 return a.a<b.a; 10 return a.b<b.b; 11 } 12 13 int n, m, a[30000], sum, ma; 14 bool b[130000], flag; 15 16 int main() { 17 cin >> n >> m; 18 ma=m*m*2; 19 for (int i=0;i<=m;++i) 20 for (int j=0;j<=m;++j) 21 if (!b[i*i+j*j]) 22 b[i*i+j*j]=true, a[++a[0]]=i*i+j*j; 23 sort(a+1, a+a[0]+1); 24 for (int i=1;i<=a[0]-n+1;++i) 25 for (int j=i+1;j<=a[0]-n+2;++j) { 26 int c=a[j]-a[i], t=n-2, no=a[j]; 27 flag=true; 28 if (no+c*t>ma) 29 break; 30 while (t--) { 31 no+=c; 32 if (!b[no]) { 33 flag=false; 34 break; 35 } 36 } 37 if (flag) { 38 sum++; 39 w[sum].a=a[i], w[sum].b=c; 40 } 41 } 42 sort(w+1, w+sum+1, cmp); 43 if (sum==0) 44 cout << "NONE\n"; 45 for (int i=1;i<=sum;++i) 46 printf("%d %d\n", w[i].a, w[i].b); 47 }
以上是关于洛谷 P1214 [USACO1.4]等差数列 Arithmetic Progressions的主要内容,如果未能解决你的问题,请参考以下文章
luogu P1214 [USACO1.4]等差数列 Arithmetic Progressions
洛谷 P1215 [USACO1.4]母亲的牛奶 Mother's Milk