USACO-Section2.1 Hamming Codes(深度优先搜索)
2017-8-15
題目描述
找出 N 個由0或1組成的編碼,每個編碼有 B 位,使得兩兩編碼之間至少有 D 個單位的 “Hamming距離”解答
使得值最小,0必然包括,從小至大往后找代碼
/* ID: 18795871 PROG: hamming LANG: C++ */ #include<iostream> #include<fstream> #include<cstring> using namespace std; const int M = 8,K = 256;ifstream fin("hamming.in"); ofstream fout("hamming.out");int N,B,D; int cnt=1,r[65];bool cal(int a,int b){int x,y,i,j,s=0;for (i=1;i<=B;i++){x=a%2;a/=2;y=b%2;b/=2;if (x!=y) s++;}if (s>=D) return true;return false; }bool res(int m){for (int i=1;i<cnt;i++){if (!cal(r[i],m)) return false;}return true; }int main() {fin>>N>>B>>D;int i;for (i=0;i<K;i++){if (res(i)) r[cnt++]=i;if (cnt>N) break;}for (i=1;i<cnt-1;i++){if (i%10==0) fout<<r[i]<<endl;else fout<<r[i]<<" ";}fout<<r[i]<<endl;return 0; }說實話,很好奇自己之前是怎么AC所有的測試數據的,可能它給的測試數據剛好滿足順著求就是它們要的解吧!我之前覺得0一定是的,那么這里我們只要順序找就可以,找到第一個與0 ” 距離 ” 大于d的即可,再繼續往下找,找到第一個與0和剛剛求得的數的 ” 距離 ” 大于d的,就這么順序往下找,一直找到n個就是我們要的解了。
好像并不是完全正確的思路,難道是因為題目要求我們 ” 使得這個N個數從第一數開始比較是最小的 “?!存在說若順著找到的最大數大于我們給定的b個字節嗎?!
我的想法是用遞歸求解這一題,step表示當前來到了第幾個,那么我們每次應該考慮選擇誰的問題了,由于我們要求的是一個升序的序列,那么我用p表示當前應該從那一個開始選擇,即比上一步的值加一,如果說這個值與之前的值的 ” 距離 ” 都大于d的話,那么我們就可以選擇它了 ,當我們選擇完畢即step==n的時候,就標記flag為true,即我們已經得到我們想要的解了。需要注意的是,我在進dfs之前已經對t數組的值進行賦值過了,那么可能會更改我們之前的值,所以我用了r數組來存儲我們最后得到的值。
/* ID: 18795871 PROG: hamming LANG: C++ */ #include <iostream> #include <fstream> using namespace std;ifstream fin("hamming.in"); ofstream fout("hamming.out");const int N = 256; int x[N+1][N+1],r[N+1],t[N+1]; int n,b,d,m; bool flag;int cal(int p,int q){int dif=0,i;for (i=0;i<b;i++){if ((p&1)!=(q&1)) dif++;p>>=1;q>>=1;}return dif; }void init(){m=1;flag=false;for (int i=0;i<b;i++){m*=2;} }void dfs(int step,int p){if (flag) return ;if (step>n) return ;if (step==n){for (int i=0;i<n;i++){r[i]=t[i];} flag=true;return ;}int i,j;for (i=p;i<=m;i++){for (j=0;j<step;j++){if (x[t[j]][i]<d) break; }if (j>=step){t[step]=i;dfs(step+1,i+1);}} }int main(){while (fin>>n>>b>>d){int i,j;init();for (i=0;i<m;i++){for (j=i+1;j<m;j++){x[i][j]=cal(i,j);}}dfs(0,0);int k=0; for (i=0;i<n;i++){if (i%10==9||i==n-1) fout<<r[i]<<endl;else fout<<r[i]<<" ";}}return 0; }或者我們可以換一個思路,step表示我們當前來到了第幾個數,那么此時我們就存在一個問題了,這個數我們選還是不選,如果說這個數滿足與之前選的數的 ” 距離 ” 都在d以上的話,那么我們才有權力選擇選或不選,否則的話,我們只能選擇不選了!如果選擇的話,當前的num數應該加一,因為我們需要滿足條件的一共n個數。需要注意的是,除了最后一行我們每行只能輸出十個。
/* ID: 18795871 PROG: hamming LANG: C++ */ #include <iostream> #include <fstream> using namespace std;ifstream fin("hamming.in"); ofstream fout("hamming.out");const int N = 256; int x[N+1][N+1],r[N+1],t[N+1]; int n,b,d,m; bool flag;int cal(int p,int q){int dif=0,i;for (i=0;i<b;i++){if ((p&1)!=(q&1)) dif++;p>>=1;q>>=1;}return dif; }void init(){m=1;flag=false;for (int i=0;i<b;i++){m*=2;} }void dfs(int step,int num){if (flag) return ;if (step>m) return ;if (step==m){if (num>=n){for (int i=0;i<=m;i++){r[i]=t[i];} flag=true;}return ;}bool f=false;for (int i=0;i<step;i++){if (!t[i]) continue;if (x[i][step]<d){f=true;break;}}if (!f){t[step]=1;dfs(step+1,num+1);t[step]=0;dfs(step+1,num);}else{t[step]=0;dfs(step+1,num);} }int main(){while (fin>>n>>b>>d){int i,j;init();for (i=0;i<m;i++){for (j=i+1;j<m;j++){x[i][j]=cal(i,j);}}dfs(0,0);int k=0; for (i=0;i<=m;i++){if (r[i]){if (k==n-1||k%10==9) fout<<i<<endl;else fout<<i<<" ";k++;}}}return 0; }總結
以上是生活随笔為你收集整理的USACO-Section2.1 Hamming Codes(深度优先搜索)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nodejs后台启动
- 下一篇: JS 全局变量、局部变量(与其他语言不太