Alice and Bob 要用到辗转相减
Alice and BobTime Limit: 1 Sec Memory Limit: 64 MB
Submit: 255 Solved: 43
Description
Alice is a beautiful and clever girl. Bob would like to play with Alice. One day, Alice got a very big rectangle and wanted to divide it into small square pieces. Now comes a problem: if all pieces of small squares are of the same size, how big could the squares be? To Alice, it's easy to solve the problem. However, she was very busy, so she asked Bob to help her. You know Alice is such a lovely girl and of course Bob won't refuse her request. But Bob is not so smart and he is especially weak in math. So he turns to you —a genius at programming. Alice will inform Bob the length and width of the big rectangle, and Bob have to tell her the longest length for the small square. All of these numbers are in their binary representations.
Input
The first line of the input is a positive integer. This is the number of the test cases followed. Each test case contains two integer L and W in their binary representation which tells you the length and width of the very big rectangle(0< L , W < 2^1000 ).There may be one or several spaces between these integers.
Output
The output of the program should consist of one line of output for each test case. The output of each test case only contains the longest length for the small squares in its binary representation. No any redundant spaces are needed.
Sample Input
2 100 1000 100 110
Sample Output
100 10
本来想用辗转相除法,但问大神后据说会超时,就用了辗转相减:
若a,b都是偶数,则gcd(a,b)=2*gcd(a/2,b/2);
若a是奇数,b是偶数,则gcd(a,b)=gcd(a,b/2);
若a,b都是奇数,则gcd(a,b)=gcd(a-b,b);
注意以上3条都要用到,单用第3条会超时。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 void mult(int p[],int x,int *len1) 5 { 6 int i,temp=0; 7 for(i=0;i<*len1;i++) 8 { 9 p[i]=p[i]*x+temp; 10 temp=p[i]/10; 11 p[i]%=10; 12 } 13 if(temp) 14 { 15 p[i]=temp; 16 (*len1)++; 17 } 18 } 19 20 void add(int p[],int q[],int *len1) 21 { 22 int i; 23 for(i=0;i<*len1;i++) 24 { 25 p[i]+=q[i]; 26 if(p[i]>9) 27 { 28 p[i]-=10; 29 p[i+1]++; 30 } 31 } 32 if(p[i]) 33 (*len1)++; 34 } 35 36 void diviT(int p[],int *len,int *rem) //'rem' is used for installing remainder 37 { 38 int m=0,i; 39 for(i=*len-1;i>=0;i--) 40 { 41 m=m*10+p[i]; 42 if(!(m/2)) 43 { 44 p[i]=0; 45 } 46 else 47 { 48 p[i]=m/2; 49 m=m%2; 50 } 51 } 52 for(i=*len-1;i>=0;i--) 53 if(p[i]) 54 { 55 *len=i+1; 56 break; 57 } 58 59 if(i<0) 60 *len=1; 61 *rem=m; 62 } 63 64 void SubStract(int p1[],int p2[],int *len1,int *len2) //辗转相减 65 { 66 int i,flag=0,len; 67 68 if(p1[0]%2==0) 69 { 70 len=*len1; 71 diviT(p1,&len,&i); 72 *len1=len; 73 } 74 if(p2[0]%2==0) 75 { 76 len=*len2; 77 diviT(p2,&len,&i); 78 *len2=len; 79 } 80 if(*len1>*len2) flag=1; 81 else if(*len1<*len2) flag=2; 82 else 83 for(i=*len1-1;i>=0;i--) 84 if(p1[i]>p2[i]) 85 { 86 flag=1; 87 break; 88 } 89 else if(p1[i]<p2[i]) 90 { 91 flag=2; 92 break; 93 } 94 if(flag==1) 95 { 96 for(i=(*len1)-1;i>=*len2;i--) 97 p2[i]=0; 98 99 for(i=0;i<*len1;i++) 100 { 101 p1[i]-=p2[i]; 102 if(p1[i]<0) 103 { 104 p1[i]+=10; 105 p1[i+1]--; 106 } 107 } 108 109 if(p1[i-1]==0) 110 (*len1)--; 111 SubStract(p1,p2,len1,len2); 112 } 113 else if(flag==2) 114 { 115 for(i=(*len2)-1;i>=*len1;i--) 116 p1[i]=0; 117 118 for(i=0;i<*len2;i++) 119 { 120 p2[i]-=p1[i]; 121 if(p2[i]<0) 122 { 123 p2[i]+=10; 124 p2[i+1]--; 125 } 126 } 127 128 if(p2[i-1]==0) 129 (*len2)--; 130 SubStract(p1,p2,len1,len2); 131 } 132 else 133 return; 134 } 135 136 int main() //transfer binary to dimcal ,convey double"长度,十进制的数组" 137 { 138 //freopen("a.txt","r",stdin); 139 int n,i,j; 140 char str1[1001]; 141 char str2[1001]; 142 int num_a[1000]; 143 int num_b[1000]; 144 int num_c[1000]; //两次出始化 145 int len1,len2; 146 147 scanf("%d",&n); 148 149 while(n--) 150 { 151 int mean=1,k=0; 152 scanf("%s",str1); 153 scanf("%s",str2); 154 155 len2=len1=1; 156 memset(num_a,0,sizeof(num_a)); 157 memset(num_b,0,sizeof(num_b)); 158 memset(num_c,0,sizeof(num_c)); 159 160 for(i=0;str1[i]!='\0';i++) 161 { 162 num_c[0]=str1[i]-'0'; 163 mult(num_a,2,&len1); //乘2 164 add(num_a,num_c,&len1); 165 } 166 for(i=0;str2[i]!='\0';i++) 167 { 168 num_c[0]=str2[i]-'0'; 169 mult(num_b,2,&len2); 170 add(num_b,num_c,&len2); 171 } 172 num_c[0]=0; 173 /* printf("num_a:"); 174 for(i=len1-1;i>=0;i--) 175 printf("%d",num_a[i]); 176 printf("\n"); 177 printf("num_b:"); 178 for(i=len2-1;i>=0;i--) 179 printf("%d",num_b[i]); 180 printf("\n"); */ 181 while(1) //为辗转相减做准备 182 { 183 if(num_a[0]%2==0&&num_b[0]%2==0) 184 { 185 mean*=2; 186 diviT(num_a,&len1,&j); 187 diviT(num_b,&len2,&j); 188 } 189 else 190 break; 191 } 192 // printf("mean=%d\n",mean); 193 SubStract(num_a,num_b,&len1,&len2); 194 if(mean!=1) 195 mult(num_a,mean,&len1); 196 /* for(i=len1-1;i>=0;i--) 197 printf("%d",num_a[i]); 198 printf("\n");*/ 199 while(1) 200 { 201 diviT(num_a,&len1,&j); 202 for(i=len1-1;i>=0&&num_a[i]==0;i--); 203 if(i>=0) 204 num_c[k++]=j; 205 else 206 { 207 num_c[k++]=j; 208 break; 209 } 210 211 } 212 for(i=k-1;i>=0;i--) 213 printf("%d",num_c[i]); 214 printf("\n"); 215 } 216 return 0; 217 }