題目地址: http://acm.sgu.ru/problem.php?contest=0&problem=499
分析思路: 直接計算兩兩的最大公約數會逾時的,我們換個角度看問題,我們找到輸入進來的數的所有約數,如果某個數出現了兩次或者以上,那麼滿足條件的最大的就是ggcd了
然後就是類似於篩法找約數, 這樣可以找到 1~n中,每個數不超過自己平方根的所有約數。 然後比平方根大的那個可以用它除出來(完全平方數要特判了)。
然後不是暴力直接從最大的開始找出現過兩次的,我們設定一個maxn來記錄就好了,每次第二次出現的數和maxn比較一下就可以了。
先看代碼:
#include<iostream>#include<vector>#include<cmath>//#include<cstdio>using namespace std;#define N 1000005vector<int> v[N+1];//int cnt[N+1]={0};bool b[N+1]={0};void pre(){ int len=sqrt(N); for(int i=1;i<=len;i++) for(int j=i*i;j<=N;j+=i) v[j].push_back(i);}int maxn=1;void check(int n){ if(b[n]) { maxn=n>maxn?n:maxn; } b[n]=1;}int main(){ pre(); int size; cin>>size; for(int i=0;i<size;i++) { int n; cin>>n; if(n<=maxn) continue; for(int j=0;j<v[n].size();j++) { check(v[n][j]); if(v[n][j]*v[n][j]!=n) check(n/v[n][j]); }// int sqrtn=sqrt(n);// for(int j=1;j<=20&&j<=sqrtn;j++)// {// if(n%j==0)// { check(j);//// if(j*j!=n) check(n/j);//// }// } }// for(int i=1000000;i>0;i--)// if(cnt[i]>=2)// {// cout<<i<<endl;// break;// } cout<<maxn<<endl; }
這個是會逾時的,因為每個數都有因子1,一般的數有因子2,我們在打表的時候選擇不打前20個約數,然後針對輸入進來的數(畢竟只有10w個少於資料範圍100w),前20個檢查一下就好了。
然後是,sqrt(n)不要出現在for(int i=0;i,<sqrt(n);i++) 這裡, 先計算出來 ,不然每次判斷都會去計算。 因為這個tle了幾次。
在總是tle卡在test 20時 ,把所有cin cout 改成了scanf printf ,可以跑到test 38 還是改進皮毛呀
最後艱難ac了,代碼:
#include<iostream>#include<vector>#include<cmath>//#include<cstdio>using namespace std;#define N 1000005vector<int> v[N+1];//int cnt[N+1]={0};bool b[N+1]={0};void pre(){ int len=sqrt(N); for(int i=21;i<=len;i++) for(int j=i*i;j<=N;j+=i) v[j].push_back(i);}int maxn=1;void check(int n){ if(b[n]) { maxn=n>maxn?n:maxn; } b[n]=1;}int main(){ pre(); int size; cin>>size;// scanf("%d",&size); for(int i=0;i<size;i++) { int n; cin>>n; // scanf("%d",&n); if(n<=maxn) continue; for(int j=0;j<v[n].size();j++) { check(v[n][j]); if(v[n][j]*v[n][j]!=n) check(n/v[n][j]); } int sqrtn=sqrt(n); for(int j=1;j<=20&&j<=sqrtn;j++) { if(n%j==0) { check(j); if(j*j!=n) check(n/j); } } }// for(int i=1000000;i>0;i--)// if(cnt[i]>=2)// {// cout<<i<<endl;// break;// } cout<<maxn<<endl; // printf("%d\n",maxn);}