2017-10-6 七道题
来源:互联网 发布:vbscript和vb 编辑:程序博客网 时间:2024/05/22 12:02
一、深搜,全排列和组合数
1、 全排列,没有重复元素
输入一行字母(长度小于等于10),输出:第一行输出全排列个数,从下一行开始按字典序输出这些字母所有可能的排列,每行一个。
#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>using namespace std;int len,a[101];char ch[101];bool b[101];long long jc[50];void jiecheng(){ jc[0]=1; for (long long i=1; i<=len; i++) jc[i]=jc[i-1]*i;}void shuchu(){ for (int i=1; i<=len; i++) putchar(ch[a[i]-1]); printf("\n");}void dfs(int num){ for (int i=1; i<=len; i++) if (!b[i]) { b[i]=true; a[num]=i; if (num==len) shuchu(); else dfs(num+1); b[i]=false; }}int main(){ freopen("pl.in","r",stdin); freopen("pl.out","w",stdout); cin>>ch; len=strlen(ch); jiecheng(); sort(ch,ch+len); printf("%lld\n",jc[len]); dfs(1); return 0;}
2、 全排列,没重复元素
桶排的思路,统计每个单词出现的个数。
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int len,m,sum=1,a[101],to[200],tot;//to数组开小 char ch[101],c[36288][10];//二维数组c用来判重bool b[101];int jc[101];void jiecheng(){ jc[0]=1; for (int i=1; i<=len; i++) jc[i]=jc[i-1]*i;}void shuchu(){ for (int i=1; i<=len; i++) putchar(a[i]); printf("\n");}void dfs(int num){ for (int i='a'; i<='z'; i++) if (to[i]) { a[num]=i; to[i]--; if (num==len) shuchu(); else dfs(num+1); to[i]++; }}int main(){ freopen("plt.in","r",stdin); freopen("plt.out","w",stdout); scanf("%s",ch); len=strlen(ch); jiecheng(); for (int i=0; i<len; i++) to[ch[i]]++; for (int i='a'; i<='z'; i++) if (to[i]) sum*=jc[to[i]]; int ans=jc[len]/sum;//方法数 printf("%d\n",ans); dfs(1); return 0;}
3、求组合,没有重复元素
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int len,m,a[20],tot;char ch[20];bool b[20];long long c[101][101];void Com(){ for (int i=1; i<=len; i++) c[i][0]=c[i][i]=1; for (int i=1; i<=len; i++) for (int j=1; j<=i; j++) c[i][j]=c[i-1][j]+c[i-1][j-1];}void print(){ for (int i=1; i<=m; i++) putchar(ch[a[i]-1]); printf("\n");}void dfs0(int num){ for (int i=1; i<=len; i++) if (!b[i]&&i>a[num-1]) { a[num]=i; b[i]=true; if (num==m) tot++; else dfs0(num+1); b[i]=false; }}void dfs(int num){ for (int i=1; i<=len; i++) if (!b[i]&&i>a[num-1]) { a[num]=i; b[i]=true; if (num==m) print(); else dfs(num+1); b[i]=false; }}int main(){ freopen("zh.in","r",stdin); freopen("zh.out","w",stdout); scanf("%s",ch); scanf("%d",&m); len=strlen(ch); sort(ch,ch+len); Com(); dfs0(1); printf("%d\n",tot); dfs(1); return 0;}
4、求组合,有重复元素
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int len,m,sum=1,a[101],to[200],tot;//to数组开小 char ch[101];bool b[101];int jc[101];int c[101][101];void jiecheng(){ jc[0]=1; for (int i=1; i<=len; i++) jc[i]=jc[i-1]*i;}void Com(){ for (int i=1; i<=len; i++) c[i][0]=c[i][i]=1; for (int i=1; i<=len; i++) for (int j=1; j<=i; j++) c[i][j]=c[i-1][j]+c[i-1][j-1];}void shuchu(){ for (int i=1; i<=m; i++) putchar(a[i]); printf("\n");}void dfs0(int num){ for (int i='a'; i<='z'; i++) if (to[i]&&i>=a[num-1]) { a[num]=i; to[i]--; if (num==m) tot++; else dfs0(num+1); to[i]++; }}void dfs(int num){ for (int i='a'; i<='z'; i++) if (to[i]&&i>=a[num-1]) { a[num]=i; to[i]--; if (num==m) shuchu(); else dfs(num+1); to[i]++; }}int main(){ freopen("zht.in","r",stdin); freopen("zht.out","w",stdout); scanf("%s",ch); scanf("%d",&m); len=strlen(ch); jiecheng(); for (int i=0; i<len; i++) to[ch[i]]++; for (int i='a'; i<='z'; i++) if (to[i]) sum*=jc[to[i]]; dfs0(1); printf("%d\n",tot); dfs(1); return 0;}
二、数论
5、下一个全排列
#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>using namespace std;int len;char ch[520];int main(){ freopen("np.in","r",stdin); freopen("np.out","w",stdout); int flag=0; cin>>ch; len=strlen(ch); for (int i=len-1; i>=0; i--) { if (ch[i-1]>ch[i]) {flag++; continue;}//找到第一个下降的 if (flag==len-1) break; int t=i; for (int j=i; j<len; j++)//在它后面找一个比它大最小的 if (ch[i-1]<ch[j]&&ch[j]<ch[t]) t=j; swap(ch[i-1],ch[t]); sort(ch+i,ch+len); break; } if (flag==len-1) for (int i=len-1; i>=0; i--) putchar(ch[i]); else printf("%s",ch); return 0;}
6、求某个排列的序号
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;char ch[50];int len;long long jc[50],sum;int judge(int x)//ch[x]位置后有多少个字母小于ch[x] { int tot=0; for (int i=x+1; i<len; i++) if (ch[x]>ch[i]) tot++; return tot;}void jiecheng(){ jc[0]=1; for (long long i=1; i<=len; i++) jc[i]=jc[i-1]*i;}int main(){ freopen("bh.in","r",stdin); freopen("bh.out","w",stdout); scanf("%s",ch); len=strlen(ch); jiecheng(); for (int i=1; i<len; i++) sum+=judge(i-1)*jc[len-i]; printf("%lld",sum+1); return 0;}
7、第m个全排列
#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>using namespace std;int len,m,a[101],small;//small:ch[i]后面有几个比ch[i]小的字母 long long total,jc[101];char ch[101],ans[101];bool b[101];void jiecheng(){ jc[0]=1; for (long long i=1; i<=len; i++) jc[i]=jc[i-1]*i;}int main(){ freopen("xh.in","r",stdin); freopen("xh.out","w",stdout); scanf("%s",ch); scanf("%d",&m); len=strlen(ch); jiecheng(); sort(ch,ch+len); m--; for (int i=0; i<len; i++) { for (int j=len; j>=0; j--) if (j*jc[len-i-1]<=m) { m-=j*jc[len-i-1]; small=j; break;}//贪心 忘记了break int t=0; for (int j=0; j<len; j++) if (!b[j])//在没用过的字母里面找第small大的(b[i]X) if (t++==small) {small=j; break;} ans[i]=ch[small]; b[small]=true; } printf("%s",ans); return 0;}
七道这么水的题都要打上一天。loli说这种题做不了怎么拿省一(省三)。马上就要被loli踢出去了。。
“怕是失了志、”
代码能力,需要马上并迫切地提升。noip可能并不需要非常高深的算法,但是需要具备把自己的想法转化成代码的能力。多刷题多总结多思考,之前欠下的债总是要还的。
阅读全文
0 0
- 2017-10-6 七道题
- 2017-10-6有感
- 学习Docker(2017-10-6)
- 2017-10-6离线赛总结
- 2017/10/6模拟赛总结
- 2017年6月22日 09:23:10
- 2017年10月6日提高组T2 挖矿
- 2017年10月6日提高组T2 挖矿
- 2017年3月6日开始,2017年10月23日回头看!
- SDUT 2017 春夏组队训练赛11 2017 6 10
- 2017/10
- 2017-6-6
- 由CSDN主办的SDCC 2017·深圳站即将于6月10日举办!
- 【持续更新】【ionic】ionic命令大全(2017年6月10日17:31:26)
- SSL2759 2017年10月6日提高组T2 挖矿(dp)
- 2017年10月6日提高组T2 猫公司
- 2017年10月6日提高组T2 有趣的异或
- 6~10
- 撩妹名词解释
- 纳米器件,量子点理论文献拾遗
- django 开发(4)
- [BZOJ1057][ZJOI2007]棋盘制作 (单调栈/悬线法)
- 【BZOJ1077】【SCOI2008】天平
- 2017-10-6 七道题
- 【Leetcode】【python】Maximum Subarray
- 【BZOJ2426】【HAOI2010】工程选址
- Mac Pro 安装mysql
- 走穿java23种设计模式-5原型模式
- 第二章数据类型十个问题
- 第二章 SQL命令参考-ALTER DATABASE
- 【BZOJ3995】【SDOI2015】道路修建
- [BZOJ2426][HAOI2010] 工厂选址 (神奇的贪心)