杭电 4712 汉明距
暴力+剪枝,或者使用随机化算法,因为结果总是在0-20之间,所以任选两个求汉明距,它不是最终结果的概率应该不超过19/20,当随机生成10^5组数据时,求出的最小值不是最终结果的概率非常低。同时当结果为0或者1时能较快的判断出来,可以特判这两种情况。
我的加了特判的代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<ctime> 5 using namespace std; 6 const int N = 100005; 7 int a[N],n; 8 bool vis[(1<<20) + 100]; 9 inline bool is1() 10 { 11 for(int i=0; i<n; ++i) 12 for(int j=0; j<20; ++j) 13 if(vis[a[i]^(1<<j)]) return true; 14 return false; 15 } 16 inline int ham(int x,int y) 17 { 18 int cnt = 0; 19 int d = a[x]^a[y]; 20 for(int i=0; i<20; ++i) 21 if(d&(1<<i)) ++cnt; 22 return cnt; 23 } 24 int memte(int t) 25 { 26 int ans = 21; 27 srand((unsigned)time(NULL)); 28 while(t--) 29 { 30 int a = rand()%n; 31 int b = rand()%n; 32 if(a == b) b = (a+1)%n; 33 int tmp = ham(a,b); 34 if(ans > tmp) ans = tmp; 35 } 36 return ans; 37 } 38 int main() 39 { 40 // freopen("in.txt","r",stdin); 41 int T; 42 scanf("%d",&T); 43 while(T--) 44 { 45 scanf("%d",&n); 46 memset(vis,0,sizeof(vis)); 47 bool flag = false; 48 for(int i=0; i<n; ++i) 49 { 50 scanf("%X",&a[i]); 51 if(!vis[a[i]]) vis[a[i]] = 1; 52 else flag = true; 53 } 54 if(flag) printf("0\n"); 55 else 56 { 57 flag = is1(); 58 if(flag) printf("1\n"); 59 else printf("%d\n",memte(100000)); 60 } 61 } 62 return 0; 63 }
运行时间为300多ms.
没加任何特判的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<ctime> 5 using namespace std; 6 const int N = 100005; 7 int a[N],n; 8 inline int ham(int x,int y) 9 { 10 int cnt = 0; 11 int d = a[x]^a[y]; 12 for(int i=0; i<20; ++i) 13 if(d&(1<<i)) ++cnt; 14 return cnt; 15 } 16 int memte(int t) 17 { 18 int ans = 21; 19 srand(time(NULL)); 20 while(t--) 21 { 22 int a = rand()%n; 23 int b = rand()%n; 24 if(a == b) b = (a+1)%n; 25 int tmp = ham(a,b); 26 if(ans > tmp) ans = tmp; 27 if(ans == 0 ) break; 28 } 29 return ans; 30 } 31 int main() 32 { 33 // freopen("in.txt","r",stdin); 34 int T; 35 scanf("%d",&T); 36 while(T--) 37 { 38 scanf("%d",&n); 39 for(int i=0; i<n; ++i) 40 scanf("%X",&a[i]); 41 printf("%d\n",memte(1000000)); 42 } 43 return 0; 44 }
运行时间接近3s,测试10^6,如果只测10^5就WA,10^7就会超时