USACO2.1 Hamming Codes【枚举+二进制处理+输出格式+题意理解】
这道题加了2个看起来奇奇怪怪的$tag$
1.输出格式:不得不说这个格式输出很恶心,很像$UVA$的风格,细节稍微处理不好就会出错。
因为这个还$WA$了一次:
1 int t=0,m=n; 2 while(m>=10) 3 { 4 for(int i=t+1;i<=t+9;i++) 5 printf("%d ",ans[i]); 6 printf("%d\n",ans[t+10]); 7 t+=10; 8 m-=10; 9 } 10 if(m==0) return 0;//一定要注意这个东西!!! 11 for(int i=t+1;i<n;i++) 12 printf("%d ",ans[i]); 13 printf("%d\n",ans[n]);
就是刚刚好个数是整十数的时候,$while$外面的循环是没有用的,循环虽然进不去,外面的$ans[n]$却能被输出,所以就会错。
其实$m$有点多余来着,只需要$t$控制就可以了,不过这么写,会直观一点吧。
2.题意理解:这道题题目描述也比较唬人,搞了好多进制转化的东西出来,然而并没有什么用,因为即使是在不同的进制下,数的大小是不会变的。
所以这个东西就是来唬人的,直接用10进制从小到大枚举就可以了。
所以题意就是求尽量小的$n$个数,使两两之间二进制不相同的位数大于等于$d$就可以了。(怎么突然想到线性基 误)
从小到大枚举,然后依次与前面的数判断不相同的位数是否大于等于$d$,如果有一个数不满足,就不能把这个数加进去。
判断2个数的二进制不相同的位数,只需要将这两个数异或一下,再求异或的结果中有多少个1就可以了(异或就是那一位两个不相同就是1,相同就是0)。
1 /* 2 ID: Starry21 3 LANG: C++ 4 TASK: hamming 5 */ 6 #include<iostream> 7 #include<string> 8 #include<cstdio> 9 #include<cstring> 10 #include<vector> 11 #include<algorithm> 12 #include<queue> 13 using namespace std; 14 #define N 70 15 #define ll long long 16 #define INF 0x3f3f3f3f 17 int n,b,d; 18 int ans[N]; 19 int bitcnt(int x) 20 { 21 int res=0; 22 while(x) 23 { 24 x&=(x-1); 25 res++; 26 } 27 return res; 28 } 29 int check(int x,int y) 30 { 31 int k=x^y; 32 return bitcnt(k); 33 } 34 int main() 35 { 36 //freopen("hamming.in","r",stdin); 37 //freopen("hamming.out","w",stdout); 38 scanf("%d %d %d",&n,&b,&d); 39 int k=1,cnt=1; 40 ans[1]=0; 41 while(cnt<n) 42 { 43 bool f=0; 44 for(int i=1;i<=cnt;i++) 45 if(check(ans[i],k)<d) 46 { 47 f=1; 48 break; 49 } 50 if(!f) ans[++cnt]=k; 51 k++; 52 } 53 int t=0,m=n; 54 while(m>=10) 55 { 56 for(int i=t+1;i<=t+9;i++) 57 printf("%d ",ans[i]); 58 printf("%d\n",ans[t+10]); 59 t+=10; 60 m-=10; 61 } 62 if(m==0) return 0;//一定要注意这个东西!!! 63 for(int i=t+1;i<n;i++) 64 printf("%d ",ans[i]); 65 printf("%d\n",ans[n]); 66 return 0; 67 }
转载请注明出处,有疑问欢迎探讨
博主邮箱 2775182058@qq.com