感觉蛮简单,就是枚举,以为能一次过,结果到case7直接tle了,自己修改了下,也去网上看了下解题报告,尝试剪枝,最后到把set<int> si,si.count()换成用一个数组判断存在才过,看来set虽然方便,可还得少用...
/* ID: hubiao cave PROG: ariprog LANG: C++ */ #include<iostream> #include<fstream> #include<string> #include<set> using namespace std; set<int> si; //set<int> ssi; struct info { int a; int b; }; set<info>sin; bool operator < (const info&,const info&); bool operator ==(const info&,const info&); int main() { ifstream fin("ariprog.in"); ofstream fout("ariprog.out"); int upper; int number; int limit; fin>>number>>upper; limit=2*upper*upper; int* ary=new int [limit+1]; for(int i=0;i<=limit;i++) { ary[i]=0; } int ul=limit/(number-1); for(int i=0;i<=upper;i++) for(int j=0;j<=upper;j++) { si.insert(i*i+j*j); ary[i*i+j*j]=1; } for(set<int>::iterator it=si.begin();it!=si.end();it++) { int now=*it; int tnow=now; int count=1; for(int i=1;i<=ul;i++) { info te; te.a=now; te.b=i; if(sin.count(te)) continue; if(now+i*(number-1)>limit) break; //while(si.count(now+i)) while((now+i<=limit)&&ary[now+i]) { now=now+i; count++; } if(count==number) { info in; in.a=tnow; in.b=i; sin.insert(in); //rec.insert(in); } if(count>number) { int n=count-number; for(int m=0;m<=n;m++) { info in; in.a=tnow+i*m; in.b=i; sin.insert(in); //rec.insert(in); } } count=1; now=*it; tnow=now; } } if(sin.size()==0) { fout<<"NONE"<<endl; return 0; } for(set<info>::iterator it=sin.begin();it!=sin.end();it++) { fout<<it->a<<" "<<it->b<<endl; } return 0; } bool operator < (const info& i1,const info& i2) { if(i1.b!=i2.b) return i1.b<i2.b; else return i1.a<i2.a; } bool operator ==(const info& i1,const info& i2) { if(i1.a==i2.a&&i1.b==i2.b) return true; return false; }