Openjudge2814:拨钟问题
来源:互联网 发布:echarts.jar源码 编辑:程序博客网 时间:2024/04/29 20:04
题目:
拨钟问题
有9个时钟,排成一个3*3的矩阵。
现在需要用最少的移动,将9个时钟的指针都拨到12点的位置。共允许有9种不同的移动。如下表所示,每个移动会将若干个时钟的指针沿顺时针方向拨动90度。
移动 影响的时钟 1 ABDE 2 ABC 3 BCEF 4 ADG 5 BDEFH 6 CFI 7 DEGH 8 GHI 9 EFHI
Input
9个整数,表示各时钟指针的起始位置,相邻两个整数之间用单个空格隔开。其中,0=12点、1=3点、2=6点、3=9点。
Output
输出一个最短的移动序列,使得9个时钟的指针都指向12点。按照移动的序号从小到大输出结果。相邻两个整数之间用单个空格隔开。
Sample Input
3 3 0
2 2 2
2 1 2
Sample Output
4 5 8 9
题意:
有9个钟,每个钟初始只能为0, 1, 2, 3, 其中0代表12点, 1代表3点, 2代表6点, 3代表9点。
有9个操作,每个操作将操作中对应序号的时钟顺时针旋转90度,问题是找出一个操作最少的组合,使得所有的时钟都变为12点。
思路:
对于列表中1到9的某一个操作,可以进行0次、1次、2次、3次,第4次就变回本身。那么一共有4^9次方个组合。可以用9个for循环,也可以用dfs。
代码:
#include <iostream>#include <cstring>#include <cstdio>#include <cstdlib>int arr[10];int vis[10];int sum[10];int ans[10];int minn=0x7FFFFFFF;using namespace std;char mp[15][15] ={ "", "ABDE", "ABC", "BCEF", "ADG", "BDEFH", "CFI", "DEGH", "GHI", "EFHI"};void dfs(int depth){ if(depth==10){ for(int i=1; i<=9; i++){ if(arr[i]%4!=0){ return; } } int asum = 0; for(int i=1; i<=9; i++){ asum += sum[i]; } if(asum<minn){ for(int i=1; i<=9; i++){ if(vis[i]==1){ ans[i] = sum[i]; } else ans[i]=0; } minn = asum; } return; } for(int i=0; i<4; i++){ for(int j=0; j<strlen(mp[depth]); j++){ // arr[mp[depth][j]-64] = (arr[mp[depth][j]-64]+3*i)%12; arr[mp[depth][j]-64] = (arr[mp[depth][j]-64]+i); } vis[depth]=(i==0)?0:1; sum[depth]=i; dfs(depth+1); for(int j=0; j<strlen(mp[depth]); j++){ //arr[mp[depth][j]-64] = (arr[mp[depth][j]-64]+12*i-3*i)%12; arr[mp[depth][j]-64] = (arr[mp[depth][j]-64]-i); } vis[depth]=0; sum[depth]=0; }}int main(){ int tmp; memset(arr, 0, sizeof(arr)); //freopen("input.txt","r", stdin); //freopen("output.txt", "w", stdout); for(int i=1; i<=9; i++){ cin>>tmp; arr[i] = tmp; } dfs(1); int tag=0; for(int i=1; i<=9; i++){ if(ans[i]!=0){ for(int j=0; j<ans[i]; j++){ if(tag==0){cout<<i; tag=-1;} else cout<<" "<<i; } } } cout<<endl; return 0;}
总结:
题意又理解偏了,(汗!--)
输入只可能为0, 1, 2, 3,我以为还有其他的输入。。于是我将0, 1, 2 , 3转化为所对应的实际的点,按理说这样模拟也可以过,但是开始忘记将minn的值进行更新,改了之后还是WA,卡了一个下午,最后问了一下同学,发现又将题意理解错了,于是我按输入只有0, 1, 2, 3来写,过了。我倒回头看原来模拟的写法,漏了指令使用次数为0时的一次模运算!!!
下面贴最开始模拟现实时钟的写法(看错题目的产物):
#include <iostream>#include <cstring>#include <cstdio>#include <cstdlib>int arr[10];int vis[10];int sum[10];int ans[10];int minn=0x7FFFFFFF;using namespace std;char mp[15][15] ={ "", "ABDE", "ABC", "BCEF", "ADG", "BDEFH", "CFI", "DEGH", "GHI", "EFHI"};void dfs(int depth){ if(depth==10){ for(int i=1; i<=9; i++){ if(arr[i]!=0){ return; } } //for(int i=1; i<=9; i++) {cout<<arr[i]<<" "; cout<<endl;} int asum = 0; for(int i=1; i<=9; i++){ asum += sum[i]; } if(asum<minn){ for(int i=1; i<=9; i++){ if(vis[i]==1){ ans[i] = sum[i]; } else ans[i]=0; } minn = asum; } return; } for(int i=0; i<4; i++){ for(int j=0; j<strlen(mp[depth]); j++){ arr[mp[depth][j]-64] = (arr[mp[depth][j]-64]+3*i)%12; } vis[depth]=(i==0)?0:1; sum[depth]=i; dfs(depth+1); for(int j=0; j<strlen(mp[depth]); j++){ arr[mp[depth][j]-64] = (arr[mp[depth][j]-64]+12*i-3*i)%12; } vis[depth]=0; sum[depth]=0; }}int main(){ int tmp; memset(arr, 0, sizeof(arr)); //freopen("input.txt","r", stdin); //freopen("output.txt", "w", stdout); for(int i=1; i<=9; i++){ cin>>tmp; if(tmp==0) arr[i]=12; else if(tmp==1) arr[i]=3; else if(tmp==2) arr[i]=6; else if(tmp==3) arr[i]=9; // else if(tmp==4) arr[i]=12; // else if(tmp==5) arr[i]=3; // else if(tmp==6) arr[i]=6; // else if(tmp==7) arr[i]=9; // else if(tmp==8) arr[i]=12; // else if(tmp==9) arr[i]=3; // else if(tmp==10) arr[i]=6; // else if(tmp==11) arr[i]=9; // else arr[i]=12; } dfs(1); int tag=0; for(int i=1; i<=9; i++){ if(ans[i]!=0){ for(int j=0; j<ans[i]; j++){ if(tag==0){cout<<i; tag=-1;} else cout<<" "<<i; } } } cout<<endl; return 0;}
写了这题收获很多!!
- Openjudge2814:拨钟问题
- 拨钟问题pku1166
- 拨钟问题
- 拨钟问题
- 枚举-拨钟问题
- openjudge-拨钟问题
- 拨钟问题
- 拨钟问题
- 拨钟问题
- 枚举-拨钟问题
- poj 1166 拨钟问题
- POJ-1816 拨钟问题
- 拨钟问题(蛮力法)
- openjudge 2814:拨钟问题
- 拨钟问题 穷举法
- 【贪心枚举】拨钟问题
- 拨钟问题的若干解法
- poj(1166)——拨钟问题
- D2. Magic Powder - 2
- 毫秒转字符串时间
- Android 用MediaCodec实现视频硬解码
- iOS笔试题之杭州卓健科技有限公司
- php学习之路---2(向服务器上传文件)
- Openjudge2814:拨钟问题
- UVA11889 Benefit
- bzoj4034: [HAOI2015]T2
- 一种通过U盘热插拔的升级方法
- HDU-5718 Oracle
- 设置可滚动的TextView
- 运行时的使用技巧
- Lightmap 色差、丢失|内存泄露
- hdu 1081 To The Max