题意:有一个序列,其中每一个数可以减 1-k,问你这个序列最大公因子是多少。
解题思路:暴力 + 数论 ,其实就是 枚举 最大公因子,然后看所有范围内的个数的和是不是等于n就行了。k其实可以反过来 代表 [x*i ,x*i+k]这个范围内的值。
解题代码:
1 // File Name: 354c.cpp 2 // Author: darkdream 3 // Created Time: 2015年03月31日 星期二 15时59分31秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #define LL long long 25 26 using namespace std; 27 int n , k ; 28 int a[400000]; 29 int hs[2000005]; 30 int mi = 1e9 ; 31 int mx = 0; 32 int main(){ 33 scanf("%d %d",&n,&k); 34 for(int i =1 ;i <= n;i ++) 35 { 36 scanf("%d",&a[i]); 37 mi = min(a[i],mi); 38 mx = max(a[i],mx); 39 hs[a[i]] ++ ; 40 } 41 for(int i = 1;i <= 2000000 ;i++) 42 hs[i] += hs[i-1]; 43 for(int i = mi ;i >= 1; i --) 44 { 45 int tsum = 0 ; 46 int tmp = 1; 47 while(tmp*i <= mx ) 48 { 49 // if(i == 4 ) 50 // printf("%d %d**%d ",min((tmp+1)*i-1,tmp*i+k),tmp*i-1,hs[min((tmp+1)*i-1,tmp*i+k)] - hs[tmp*i-1]); 51 tsum += hs[min((tmp+1)*i-1,tmp*i+k)] - hs[tmp*i-1]; 52 tmp ++ ; 53 } 54 if(tsum == n) 55 { 56 printf("%d ",i); 57 return 0 ; 58 } 59 // printf("%d %d ",tsum,i); 60 } 61 return 0; 62 }