[USACO1.4]等差数列 Arithmetic Progressions
预处理出来所有的双平方数,然后枚举地一个和第二个数。
中间要加一个剪枝。因为知道了首项和公差和项数就能求出最后一项是不是可行的了。
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include <ctime>
#include <set>
#include <map>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define go(i,k) for(int i=head[k],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
using namespace std;
typedef long long ll;
typedef double db;
const int inf=0x3f3f3f3f;
inline int rd() {
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
return x*f;
}
const int N=256;
int sqr[N*N<<1];
bool vis[N*N<<2];
int n,m,cnt;
struct Node{int a,b;}q[10005];
bool cmp(Node x,Node y) {return x.b==y.b?x.a<y.a:x.b<y.b;}
bool cmp2(int x,int y) {return x>y;}
int main() {
#ifdef HSZ
freopen(".in","r",stdin);
freopen(".out","w",stdout);
#endif
n=rd(),m=rd();
int ans=0;
fo(i,0,m)
fo(j,0,m)
if(!vis[i*i+j*j]) vis[i*i+j*j]=1,sqr[++cnt]=i*i+j*j;
sort(sqr+1,sqr+1+cnt);
fo(i,1,cnt)fo(j,i+1,cnt){
int d=sqr[j]-sqr[i],p=sqr[i],cnt=0;bool flag=0;
if(p+d*(n-1)>m*m*2) break;
while(vis[p]) {
cnt++;
p+=d;
if(cnt==n) {q[++ans]=(Node){sqr[i],d};flag=1;break;}
}
}
sort(q+1,q+1+ans,cmp);
if(!ans) {puts("NONE");return 0;} fo(i,1,ans) printf("%d %d\n",q[i].a,q[i].b);
return 0;
}
我是咸鱼。转载博客请征得博主同意Orz