HDU 4712 Hamming Distance
这绝对是个阴谋。
题目链接:http://code.hdu.edu.cn/showproblem.php?pid=4712
10w的数据量,明显不能暴力枚举。
以为有规律可寻,遂在演草纸上各种XOR。
结果看题解,随机数。
我想,这一定会成为ACMer解题方法的一大奇葩。
我想说的就是:太水啦,坑爹坑妈还要坑我!
好吧,题意很容易看懂,就是任意两个16进制字符串XOR,在 所有结果中,求结果以二进制表示时,含1个数最少是多少。
不解释,上代码。
1 #include<stdio.h> 2 #include<iostream> 3 using namespace std; 4 #include<queue> 5 #include<math.h> 6 #include<algorithm> 7 #include<string.h> 8 #include<stdlib.h> 9 10 #define repA(p,q,i) for( int (i)=(p); (i)!=(q); ++(i) ) 11 #define repAE(p,q,i) for( int (i)=(p); (i)<=(q); ++(i) ) 12 #define repD(p,q,i) for( int (i)=(p); (i)!=(q); --(i) ) 13 #define repDE(p,q,i) for( int (i)=(p); (i)>=(q); --(i) ) 14 #define round 80000 15 #define range 100010 16 #define MAXN 0x3f3f3f3f 17 18 int flag[16][16]; // store the number of '1' when you XOR A and B 19 // both A B are in decimal 20 char s[range][6]; // store character string 21 22 void initial(); 23 int num( int p, int q ); 24 25 int main() 26 { 27 initial(); 28 int test,n; scanf("%d",&test); 29 while(test--) 30 { 31 scanf("%d",&n); 32 repA(0,n,i) 33 scanf("%s",&s[i]); 34 srand( (unsigned) time (NULL) ) ; 35 int p,q,temp; 36 int ans = MAXN ; 37 repA(0,round,i) 38 { 39 p = rand()%n ; 40 q = rand()%n ; 41 while( p == q ) 42 p = rand()%n ; 43 temp = num(p,q) ; 44 if(temp < ans) 45 ans = temp ; 46 } 47 printf("%d\n",ans); 48 } 49 return 0; 50 } 51 52 void initial() 53 { 54 int all,temp; 55 repA(0,16,i) 56 { 57 repA(0,16,j) 58 { 59 all=0; 60 temp = i ^ j ; 61 repA(0,4,k) 62 { 63 if( (1<<k) & temp ) 64 ++all ; 65 } 66 flag[i][j]=all; 67 //printf("%d ",all); 68 } 69 //printf("\n"); 70 } 71 return ; 72 } 73 74 int num( int p, int q ) 75 { 76 int all=0; 77 int m,n; 78 repA(0,5,i) 79 { 80 if( s[p][i]>='0' && s[p][i]<='9' ) 81 m = s[p][i] - '0' ; 82 else m = s[p][i] - 'A' + 10 ; 83 if( s[q][i]>='0' && s[q][i]<='9' ) 84 n = s[q][i] - '0' ; 85 else n = s[q][i] - 'A' + 10 ; 86 all += flag[m][n] ; 87 } 88 return all; 89 }
网上有个人随机6w次就过了,但是我的代码要是设成6w的话就WA了。我比较了一下,他在随机数的处理上和我略有不同,下面是他的随机方法。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<ctime> 5 #include<cstdlib> 6 using namespace std; 7 8 int cmp[16][16]; 9 10 char data[1000005][6]; 11 12 int fun(int q,int w) 13 { 14 int a,b; 15 int ret = 0; 16 for(int i=0;i<5;i++) 17 { 18 char x = data[q][i]; 19 char y = data[w][i]; 20 if(x>='0' && x<='9') 21 a=x-'0'; 22 else 23 a=x-'A'+10; 24 25 if(y>='0' && y<='9') 26 b=y-'0'; 27 else 28 b=y-'A'+10; 29 30 ret += cmp[a][b]; 31 } 32 return ret; 33 } 34 35 int main() 36 { 37 for(int i=0;i<=15;i++) 38 { 39 for(int j=0;j<=15;j++) 40 { 41 int ans=0; 42 int tmp = i^j; 43 for(int k=0;k<4;k++) 44 if((1<<k) & tmp) 45 ans++; 46 //cout<<i<<" "<<j<<" "<<ans<<endl; 47 cmp[i][j] = ans; 48 } 49 } 50 51 int n; 52 int t; 53 scanf("%d",&t); 54 while(t--) 55 { 56 scanf("%d",&n); 57 for(int i=1;i<=n;i++) 58 scanf("%s",data[i]); 59 60 int ans = 0x3f3f3f3f; 61 srand( (unsigned)time( NULL ) ); 62 for(int i=1;i<=60000;i++) 63 { 64 int a = rand()%n+1; 65 int b = rand()%n+1; 66 if(a==b) 67 b = b%n+1; 68 int tmp = fun(a,b); 69 if(tmp < ans) 70 ans = tmp; 71 } 72 73 cout<<ans<<endl; 74 } 75 76 return 0; 77 }
To Be The Best Of Yourself