https://www.luogu.org/problemnew/show/P1214
首先暴力枚举可以凑出来的数,对于每个数进行标记。
对于每一个等差数列,当我们知道前两个数后即可以得出整个序列,那么我们就要判断序列中的每一个数是否被标记过,合法记录答案。
最后对于答案进行排序,输出。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <queue> using namespace std; #define LL long long int a[100000],tot,cnt,n,m; bool vis[2000000]; struct ahah { int s,k; } ans[2000006]; bool cmp(ahah a,ahah b) { return a.k<b.k; } void prepare(int x) { for(int i=0; i<=x; i++) { for(int j=0; j<=x; j++) { a[++tot]=i*i+j*j; } } sort(a+1,a+1+tot); tot=unique(a+1,a+1+tot)-a-1; for(int i=1; i<=tot; i++)vis[a[i]]=1; } int main() { scanf("%d%d",&n,&m); prepare(m); for(int i=1; i<=tot; i++) { if(a[i]>m*m*2)break; for(int j=i+1; j<=tot; j++) { int d=a[j]-a[i]; if(a[i]+(n-1)*d > m*m*2)break; for(int k=2; k<=n; k++) { if(!vis[a[i]+d*(k-1)])break; if(k==n)ans[++cnt].s=a[i],ans[cnt].k=d; } } } if(cnt==0)printf("NONE"); else { sort(ans+1,ans+1+cnt,cmp); for(int i=1; i<=cnt; i++)printf("%d %d ",ans[i].s,ans[i].k); } }
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <queue> using namespace std; #define LL long long int a[100000],tot,cnt,n,m; bool vis[2000000]; struct ahah { int s,k; } ans[2000006]; bool cmp(ahah a,ahah b) { return a.k<b.k; } void prepare(int x) { for(int i=0; i<=x; i++) { for(int j=0; j<=x; j++) { a[++tot]=i*i+j*j; } } sort(a+1,a+1+tot); tot=unique(a+1,a+1+tot)-a-1; for(int i=1; i<=tot; i++)vis[a[i]]=1; } int main() { scanf("%d%d",&n,&m); prepare(m); for(int i=1; i<=tot; i++) { if(a[i]>m*m*2)break; for(int j=i+1; j<=tot; j++) { int d=a[j]-a[i]; if(a[i]+(n-1)*d > m*m*2)break; for(int k=2; k<=n; k++) { if(!vis[a[i]+d*(k-1)])break; if(k==n)ans[++cnt].s=a[i],ans[cnt].k=d; } } } if(cnt==0)printf("NONE"); else { sort(ans+1,ans+1+cnt,cmp); for(int i=1; i<=cnt; i++)printf("%d %d ",ans[i].s,ans[i].k); } }