thejacoblu

EOJ 3023 字符组合

3.30更新

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <algorithm>
 4 #include <set>
 5 using namespace std;
 6 int main()
 7 {
 8     int T;cin>>T;
 9     for(int m=0;m<T;m++)
10     {
11         string s;cin>>s;
12         sort(s.begin(),s.end());
13         s.resize(unique(s.begin(),s.end())-s.begin());
14 
15         int ll=s.size();
16         int sum=~((-1)<<ll)+1;
17 
18         set<string> ans;
19         while(sum-->1)
20         {
21             string tmp;
22             for(int d=1,i=0;i<ll;d=d<<1,i++)
23                 if(sum&d) tmp+=s[i];
24             ans.insert(tmp);
25         }
26         printf("case #%d:\n",m);
27         for(string x:ans)cout<<x<<endl;
28 
29 
30     }
31     return 0;
32 }

使用位运算更简便,更新排序unique的操作,并且使用set容器。

 


 

3.29更新

 1 #include<bits/stdc++.h>
 2 #define ALL(x) x.begin(),x.end()
 3 using namespace std;
 4 set<string> ans;
 5 string s,ss,ret;
 6 void comb(int n,string s){/*我这个也是递归*/
 7 
 8     for(int i=n;i<ss.size();i++){
 9         ans.insert(s+ss[i]);
10         comb(i+1,s+ss[i]);
11     }
12 }
13 int main()
14 {
15     int T;cin>>T;
16     for(int m=0;m<T;m++){
17         cin>>s;
18         ss=ret=string{};
19         ans.clear();
20         sort(ALL(s));
21         unique_copy(ALL(s),back_inserter(ss));
22         comb(0,ret);
23         printf("case #%d:\n",m);
24         for(string x:ans)   cout<< x <<endl;
25     }
26     return 0;
27 }

用递归方式实现,核心代码只需3行!

既然题目说明ab和ba等价,每次只需要从上一个指定位置向后看就好了。比如递归b的时候就不会从a开始了。

一开始用回溯,加加减减的没有必要,既然递归的局部变量在函数退出时消亡,干脆直接传进去好了。

 

 


输入一个由字母组成的字符串 S(1≤长度≤16),按字典序输出由 S 中不同字符组成的所有字符组合(每个组合中的字符也按字典序排列)。

例如:“cbaabc” 中的不同字符是 ‘a’、‘b’、‘c’ 共 3 个,则 1 个字符组成的组合是 “a”、“b”、“c”3 种,2 个字符组成的组合是 “ab”、“bc”、“ac”3 种,3 个字符组成的组合是 “abc”1 种。注意:“ab” 和 “ba” 由相同字符组合而成,因此可认为是同一个组合。那么这个例子共有 7 种组合,按序分别为 “a”、“ab”、“abc”、“ac”、“b”、“bc”、“c”。


 

 

 1 #include <iostream>
 2 #include <math.h>
 3 #include <algorithm>
 4 #include <vector>
 5 using namespace std;
 6 int main()
 7 {
 8     int T;cin>>T;
 9     for(int m=0;m<T;m++)
10     {
11         int flag[52]={0};char c;
12         vector<char> v;
13         string s;cin>>s;
14         for(char x:s) v.push_back(x);
15         sort(v.begin(),v.end());
16         v.resize(unique(v.begin(),v.end())-v.begin());
17 
18         int ll=v.size();
19         long long sum=0;
20         for(int i=0;i<ll;i++)
21             sum+=pow(2,i);
22         vector<string > ans;
23         for(;sum>=1;sum--)
24         {
25             string tmp;
26             for(int i=ll-1,d=1;i>=0;i--,d<<=1)
27                 if(sum&d) tmp.insert(tmp.begin(),v[i]);
28             ans.push_back(tmp);
29         }
30         sort(ans.begin(),ans.end());
31         printf("case #%d:\n",m);
32         for(int i=0;i<ans.size();i++)
33             cout<<ans[i]<<endl;
34 
35 
36     }
37     return 0;
38 }

 排序去重后二进制枚举即可。

posted @ 2018-03-23 11:05  thejacoblu  阅读(413)  评论(0编辑  收藏  举报