2022春每日一題:Day 39
阿新 • • 發佈:2022-03-16
題目:[USACO1.4]等差數列 Arithmetic Progressions
一個很顯然的做法,列舉公差,首項,p,q這樣的話複雜度爆炸,不過可以肯定的一點,如果我們這樣做,找到了答案就可以直接輸出
考慮優化,m很小,可以打表把p2+q2所有可能的答案用桶存下來,列舉之用一個數,另一個數直接通過數學計算得出,在中途無解時,直接跳出,剪枝。
這樣的話已經可以通過本題,但是考慮繼續優化,不難發現n>=4時,公差一定是4的倍數,因為我們知道i與i+1是互質的,而n=3時,0,1,2是允許的,而且2^2是4,所以公差至少為4。
這樣每個點都可以跑進1s內
程式碼:
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <vector> #include <cmath> const int N=250*255*2; using namespace std; int n,m,maxs,ret,t[N],s[N],cnt; int main() { scanf("%d %d",&n,&m); maxs=m*m+m*m; for(int i=0;i<=m;i++) for(int j=0;j<=m;j++) t[i*i+j*j]=1; for(int d=1;d<=maxs;) { for(int f=0;f+(n-1)*d<=maxs;f++) { int cnt=0; for(int i=1;i<=n;i++) { int flag=1; if(!t[f+(i-1)*d]) flag=0; cnt+=flag; if(cnt!=i) break; } if(cnt==n) printf("%d %d\n",f,d),ret++; } if((n-1)*d>maxs) break; if(n==3) d++; else { d+=4; if(d==5) d--; } } if(!ret) puts("NONE"); return 0; }