CodeForces 37C (dfs+排序)
题目:http://codeforces.com/problemset/problem/37/C
这题刚开始做的时候真无从入手,要求任意一个字符串都不是其他字符串的前缀,后来问来神牛,是基于哈夫曼树的原理来做的。。
比如 一棵树
深度
-1 0
/ \
0 1 1
/ \ / \
0 1 0 1 2
字符串最小是1位,所以从深度1开始;若输入的数字为1,2,3
如果1选了深度为1的0 ,2和3就不能选深度为2的0以及深度为2的0以下的分支,这样1的0会成为2和3的前缀,同理可得右边的1
最后排序还原位置的时候真花了点时间,才知道对map的value值进行排序要借助pair 和vector
View Code
1 # include<iostream> 2 # include<stdio.h> 3 # include<map> 4 # include<vector> 5 # include<algorithm> 6 # include<string.h> 7 using namespace std; 8 int vis[1001],used[1001][3],num,n; 9 int vis2[1001],a[1001]; 10 map<string,int> p; 11 typedef pair<string,int>Pair; 12 char s[1001]; 13 vector<Pair> vec; 14 int comp(const Pair &x,const Pair &y) 15 { 16 return x.second<y.second; 17 } 18 19 inline int check(int l) 20 { 21 for(int i=0;i<n;++i) 22 if(!vis2[i] && a[i] == l) 23 { 24 vis2[i] = 1; 25 return i; 26 } 27 return 0; 28 } 29 30 void dfs(int l) 31 { 32 s[l] = '\0'; 33 if(num>=n)return; 34 if(p.count(s)) return; 35 if(vis[l]) 36 { 37 vis[l]--; 38 p.insert(make_pair(s,check(l))); 39 //cout<<s<<endl; 40 num++; 41 return; 42 } 43 for(int i=0;i<=1;++i) 44 { 45 if(!used[l][i]) 46 { 47 used[l][i]++; 48 if(i) s[l] = '1'; 49 else s[l] = '0'; 50 dfs(l+1); 51 used[l][i]--; 52 } 53 } 54 } 55 56 int main() 57 { 58 while(~scanf("%d",&n)) 59 { 60 p.clear(); 61 num = 0; 62 memset(vis2,0,sizeof(vis2)); 63 memset(vis,0,sizeof(vis)); 64 memset(used,0,sizeof(used)); 65 for(int i=0;i<n;++i) 66 { 67 scanf("%d",&a[i]); 68 vis[a[i]]++; 69 } 70 dfs(0); 71 if(num<n) cout<<"NO"<<endl; 72 else 73 { 74 cout<<"YES"<<endl; 75 map<string,int>::iterator it; 76 for(it=p.begin();it!=p.end();it++) 77 { 78 vec.push_back(make_pair(it->first,it->second)); 79 } 80 sort(vec.begin(),vec.end(),comp); 81 for(vector<Pair>::iterator it=vec.begin();it!=vec.end();it++) 82 { 83 cout<<it->first<<endl; 84 } 85 } 86 } 87 return 0; 88 }


浙公网安备 33010602011771号