2121. 【2016-12-31普及组模拟】简单游戏
来源:互联网 发布:网络许可盈利 编辑:程序博客网 时间:2024/04/29 18:27
【题目描述】
Charles和sunny在玩一个简单的游戏。若给出1~n的一个排列A,则将A1、A2相加,A2、A3相加……An-1、An相加,则得到一组n-1个元素的数列B;再将B1、B2相加,B2、B3相加,Bn-2、Bn-1相加,则得到一组n-2个元素的数列……如此往复,最终会得出一个数T。而Charles和sunny玩的游戏便是,Charles给出n和T,sunny在尽可能短的时间内,找到能通过上述操作得到T且字典序最小的1~n的排列。(sunny大声说:“What an easy game!”,接着几下就给出了解),Charles觉得没意思,就想和你玩,当然,你可以用一种叫做“电子计算机”的东西帮你。
【输入】
本题有多组数据,对于每组数据:一行两个整数n(0<n<=20),t即最后求出来的数。两个0表示输入结束。
【输出】
对于每组测试数据输出一行n个整数,用空格分开,行尾无多余空格,表示求出来的满足要求的1~n的一个排列。
【样例输入】
4 163 90 0
3 1 2 41 3 2
1)
3 1 2 4
3+1=4 1+2=3 2+4=6
4+3=7 3+6=9
7+9=16
2)
1 3 2
1+3=4 3+2=5
4+5=9
比赛思路:比赛的思路只有暴力了,不管了,果断打了一个爆搜,于是时间超限拿了个40分,如下所述:
#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>using namespace std;int a[21][21];int tf,sum,t,n;int s[21];int b[21];bool pd[21];void yanghui(void){ a[1][1]=1; for (int i=2;i<=20;i++) { for (int j=1;j<=i;j++) { a[i][j]=a[i-1][j]+a[i-1][j-1]; } }}void dg(int n,int k){ if (tf==1) return; if (sum>t) return; if (sum+(s[n]-s[k-1])*n<t) return; if ((k-1>(n+1)/2)&&(b[n-k+2]>b[k-1])) return; if (k==n+1) { if (sum==t) { for (int i=1;i<=n;i++) { printf("%d ",b[i]); } printf("\n"); tf=1; } return; } else { for (int i=1;i<=n;i++) { if (pd[i]==false) { sum=sum+i*a[n][k]; b[k]=i; pd[i]=true; dg(n,k+1); if (tf==1) return; sum=sum-i*a[n][k]; pd[i]=false; } } }}int main(){ freopen("easy.in","r",stdin); freopen("easy.out","w",stdout); yanghui(); while (1!=0) { memset(pd,false,sizeof(pd)); tf=0;sum=0; scanf("%d%d",&n,&t); if ((n==0)&&(t==0)) { return 0; } for (int i=1;i<=n;i++) s[i]=s[i-1]+a[n][i]; dg(n,1); } return 0;}
剪枝一:加一个小小的优化,就是在确定第X个数时,保证新求出来的y不能大于T,加上这个优化后,可以得40分;
剪枝二:由于C(N-1,i)=C(N-1,N-1-i),具有对称性,题目又要求最小字典序列,所以在枚举时当x>n div 2 时,要保证a[x]>a[N+1-x],这样程序速度会提高,但是该题还是只能得40分;
剪枝三:当枚举到第X个数时,剩余的N-X个数,与剩余的N-X个系数一一对应,让大数和大系数相乘,小数和小系数相乘可以得到最大值,让大数和小系数相乘,小数和大系数相乘可以得到最小值,如果剩余的值不在这个范围内,就不要搜下去,这样可以大大优化,拿样例举例来说:
N=4,T=16
当枚举a[1]=1时,剩余16-1*1=15,剩余的未放置的数为2,3,4,剩余的系数为1,3,3,这样最大值为4*3+3*3+2*1=23,最小值为4*1+3*3+2*3=19,都超过了15,所以第一个数不能选1。
wow,看了我大概半个小时后终于明白,于是赶紧码了出来,于是AC。题解如下:
#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>using namespace std;int n,t;bool tf=false;int pd[110],da[110];int f[110][110];bool p[110];int min1(int x){int j=0;int minn=0;for (int i=x+1;i<=n;i++) j++,pd[j]=f[n][i];for (int i=1;i<=n-x;i++){for (int j=i+1;j<=n-x;j++){if (pd[i]>pd[j]){int t;t=pd[i];pd[i]=pd[j];pd[j]=t;}}}j=1;for (int i=n;i>=1;i--) {if (p[i]==false) minn=minn+pd[j]*i,j++;}return minn;}int max1(int x){int j=0;int maxx=0;for (int i=x+1;i<=n;i++){j++;pd[j]=f[n][i];}for (int i=1;i<=n-x;i++){for (int j=i+1;j<=n-x;j++){if (pd[i]>pd[j]){int t;t=pd[i];pd[i]=pd[j];pd[j]=t;}}}j=1;for (int i=1;i<=n;i++){if (p[i]==false) maxx=maxx+pd[j]*i,j++; }return maxx;}void dfs(int x,int hh){int i,j,k;if (tf==true) return;if (x==n+1){if (t==hh){for (int i=1;i<=n;i++) printf("%d ",da[i]);printf("\n");tf=true;}return;}else{for (int i=1;i<=n;i++){if (p[i]==false){if (x>n/2) {if (da[n-x+1]>i) continue;}if (hh+i*f[n][x]>t) continue;p[i]=true;if ((t-hh-i*f[n][x]>=min1(x))&&(t-hh-i*f[n][x]<=max1(x))){da[x]=i;dfs(x+1,hh+i*f[n][x]);p[i]=false;da[x]=0;}else p[i]=false;}}}}void yanghui(void){f[1][1]=1;for (int i=2;i<=n;i++){for (int j=1;j<=i;j++){f[i][j]=f[i-1][j-1]+f[i-1][j]; }}}int main(){ freopen("easy.in","r",stdin);freopen("easy.out","w",stdout);while (1!=0){scanf("%d%d",&n,&t);yanghui();if ((n==0)&&(t==0)) return 0;memset(pd,0,sizeof(pd));memset(p,false,sizeof(p));tf=false;dfs(1,0);}return 0;}
其实做完之后才发现这道题很水……(刮开有惊喜)
- 2121. 【2016-12-31普及组模拟】简单游戏
- 【2016-12-31普及组模拟】抄书
- 2017.1.12【初中部 】普及组模拟赛C组 简单游戏 题解
- jzoj 1591. 【普及模拟】游戏
- JZOJ__Day 4:【普及模拟】游戏
- 【12普及模拟】采药
- jzoj 1568. 【普及模拟】石子游戏
- jzoj 1591. 【普及模拟】游戏 解题报告
- 普及练习场之简单的模拟
- 普及练习场 简单的模拟 机器翻译
- 普及练习场 简单的模拟 笨小猴
- 【模拟】【noip2012普及组】寻宝
- 【NOIP普及组模拟】采药
- 【普及组模拟赛】Note
- 【12普及模拟】DNA排序
- 2017.1.19【初中部 】普及组模拟赛C组 小x的游戏 题解
- 2017.1.20【初中部 】普及组模拟赛C组 鸡腿の游戏 题解
- NOIP2015普及组-扫雷游戏
- javaWeb 各类资源和页面的地址和路径的写法。
- Java 操作按照尺寸裁剪图片
- Android 带文字的进度条,文字颜色随进度条的增加而渐变的效果
- Ubuntu 出现apt-get: Package has no installation candidate问题
- Android 获取手机唯一标识 IMEI号 应用名称、版本名、版本号
- 2121. 【2016-12-31普及组模拟】简单游戏
- DNS域名解析详解
- scrapy-splash 爬虫渲染异步加载,ajax
- 智能家电之蓝牙控制
- MFC:Tab Control 控件的使用
- 有关Python线程、函数、锁相关的一个程序
- Android安卓使用iosocket进行Socket通信简单封装优雅写代码
- Android studio中正确引入so文件的方法
- Scala学习整理[第十九章 泛型和约束系统]<Programming In Scala>