codeforces gym 100463I Yawner
//这题挂得让我怀疑我最近是不是做了什么坏事
题意:一个人有两个集合,先在其中一个集合选一个数x,然后向右走x布,然后再在另一个集合里选一个数y,向左走y步,问是否能走完数轴上所有点。
解:显然是求gcd(ai-bj)的值是不是1,然后有gcd(ai-bj)=gcd(ai-b1,ai-b2,ai-b3,........)=gcd(ai-b1,b2-b1,b3-b1,b4-b1.....)=gcd(gcd(ai-b1),gcd(bj-b1)),然后就可以把a,b分开求了。另外假如求出来gcd值是2,那么要特殊讨论a中是否有奇数,即 即我们先前的假设是步数一样,但实际上a可以比b多走一步。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #include<stack> 11 #include<string> 12 #define LL long long 13 14 const int MAXN=100007; 15 const int MAXM=0; 16 const int INF=2000000000; 17 18 using namespace std; 19 20 int a[MAXN],b[MAXN]; 21 int n,m,cas=0; 22 23 int gcd(int a,int b){ 24 if (b==0) return a; 25 return gcd(b,a%b); 26 } 27 28 bool check(int x){ 29 if (x>2) return 0; 30 bool flag=0; 31 for (int i=0;i<n;i++){ 32 if (a[i]&1) flag=true; 33 } 34 if (x==2 && !flag) return 0; 35 return 1; 36 } 37 38 int main(){ 39 while (scanf("%d%d",&n,&m)==2){ 40 if (n==0 && m==0) break; 41 cas++; 42 for (int i=0;i<n;i++) scanf("%d",&a[i]); 43 for (int i=0;i<m;i++) scanf("%d",&b[i]); 44 sort(a,a+n); 45 sort(b,b+m); 46 if (a[n-1]<b[0] || a[0]>b[m-1]){ 47 printf("Case %d: YES\n",cas); 48 continue; 49 } 50 int ans=a[0]-b[0]; 51 for (int i=1;i<n;i++) ans=gcd(ans,a[i]-b[0]); 52 for (int i=1;i<m;i++) ans=gcd(ans,b[i]-b[0]); 53 if (!check(abs(ans))){ 54 printf("Case %d: YES\n",cas); 55 } 56 else{ 57 printf("Case %d: NO\n",cas); 58 } 59 } 60 return 0; 61 } 62 /* 63 2 2 64 1 65 3 66 1 67 3 68 69 2 5 70 10 71 20 72 1 73 2 74 3 75 4 76 5 77 3 3 78 3 79 6 80 9 81 3 82 6 83 9 84 2 2 85 1 86 2 87 1 88 2 89 0 0 90 */