湖南省第八届省赛题!!csu1119 Collecting Coins
来源:互联网 发布:淘客网站源码建立 编辑:程序博客网 时间:2024/05/19 22:01
/*题意~:要你求能吃掉硬币的最多的个数,O代表石头,X代表障碍物 .代表路 C代表硬币。石头只能推一次推完就滚到在你正对着石头的后面一个位置就变成障碍,石头只能在后面为“·”的时候推,其余时候不能推。思路: 刚开始用dfs爆搜~~结果想错了,那样肯定超时,以吃硬币判重,然后那里一共有最多10枚硬币,那就是vis【10】【10】【10】了,一百个格子,每个格子最多可以跑10个,也就是dfs有100^10次方个节点。直接爆搜果断超。后来看了下网上的思路:然后代码是自己写的,先用dfs或bfs把不推石头就能吃掉的硬币吃掉,然后枚举石头每个石头全排列推就是5!石头的全排列,因为有可能先退这个石头比先退那个石头吃的多些,然后每个石头有四个方向可以推。也就是没个石头有四种状态。中然后最多有100个格子,也就是最多 5!*4*100个节点。这样比之前还是少了很多很多了。 然后推一次石头跑一次dfs,求硬币最多者+上之前没推石头的就是答案了~~*/#include<stdio.h>#include<string.h>#include<stdlib.h>struct node{ int x,y,flag;};node st[6];node ccc[11];int n,m;int vis[30][30];char map[30][30];int zx,zy;int cnt;int res,ans,ans1;int c,co;int dir[4][2]={1,0,-1,0,0,1,0,-1};int jude(int x,int y){ if(x<1||x>n||y<1||y>m) return 0; return 1;}void dfs(int x,int y){ if(map[x][y]=='C') res++,map[x][y]='.'; vis[x][y]=1; for(int i=0;i<4;i++) { int xx=x+dir[i][0]; int yy=y+dir[i][1]; if(!jude(xx,yy)||vis[xx][yy]||map[xx][yy]=='O'||map[xx][yy]=='X') continue; dfs(xx,yy); }}void dfs4(int x,int y,node *df,int &co)//推完一个石头能吃到的金币个数{ if(map[x][y]=='C') res++,map[x][y]='.',df[co].x=x,df[co++].y=y;//记录金币的位置,后面回溯。 vis[x][y]=1; for(int i=0;i<4;i++) { int xx=x+dir[i][0]; int yy=y+dir[i][1]; if(!jude(xx,yy)||vis[xx][yy]||map[xx][yy]=='O'||map[xx][yy]=='X') continue; dfs4(xx,yy,df,co); }}int dfs1(int x,int y,int zx,int zy)//判断是否能到达推石头的那个点。{ vis[x][y]=1; if(x==zx&&y==zy) return 1; for(int i=0;i<4;i++) { int xx=x+dir[i][0]; int yy=y+dir[i][1]; if(!jude(xx,yy)||vis[xx][yy]||map[xx][yy]=='X'||map[xx][yy]=='O') continue; if(dfs1(xx,yy,zx,zy)) return 1; } return 0;}void solove(int num,int sum)//第几个石头,金币和{ if(num==cnt-1)//最后一个石头推完 { if(ans1<sum) ans1=sum; return ; } if(ans+ans1==c) return ; for(int i=1;i<cnt&&ans+ans1<c;i++)//暴力枚举石头 { if(!st[i].flag) continue ; st[i].flag=0; for(int j=0;j<4;j++)//枚举方向 { int xx=st[i].x+dir[j][0];//根据你的位置得到的石头的前后位置。 int yy=st[i].y+dir[j][1]; int x2=st[i].x-dir[j][0]; int y2=st[i].y-dir[j][1]; if(!jude(xx,yy)||map[xx][yy]=='C'||map[xx][yy]=='O'||map[xx][yy]=='X') continue;//当石头后面不为空或者出界 if(!jude(x2,y2)||map[x2][y2]=='O'||map[x2][y2]=='X') continue;//当人站的那个位置还有石头或者为障碍 memset(vis,0,sizeof(vis)); if(!dfs1(zx,zy,x2,y2)) continue;//当人不能到达推石头的那个位置 map[st[i].x][st[i].y]='.';//能推就把石头那个位置变成路 map[xx][yy]='X';//石头后面的位置变成障碍 memset(vis,0,sizeof(vis)); int co=0; node *df=(node*)malloc(sizeof(node)*10);//最多是个金币,用来保存这一轮完石头所吃的金币位置用于后面的回溯 res=0; dfs4(zx,zy,df,co);//推完这次石头然后去吃硬币 solove(num+1,sum+res);//继续往下面枚举石头 for(int k=0;k<co;k++)//回溯地图上的金币 { map[df[k].x][df[k].y]='C'; } map[st[i].x][st[i].y]='O';//回溯石头的位置 map[xx][yy]='.'; } st[i].flag=1; if(ans1<sum) ans1=sum;//取最大 }}int main(){ int t; scanf("%d",&t); while(t--) { scanf("%d %d",&n,&m); cnt=1; c=0; for(int i=1;i<=n;i++) { scanf("%s",map[i]+1); for(int j=1;j<=m;j++) { if(map[i][j]=='S') { zx=i; zy=j; map[i][j]='.'; } if (map[i][j] == 'C') c++; if(map[i][j]=='O') { st[cnt].x=i,st[cnt].y=j; st[cnt++].flag=1; } } } res=0; memset(vis,0,sizeof(vis)); dfs(zx,zy);//不推石头直接能吃的金币个数 ans=res; ans1=0; solove(0,0); printf("%d\n",ans+ans1); }}
阅读全文
0 0
- 湖南省第八届省赛题!!csu1119 Collecting Coins
- 1119 Collecting Coins 湖南省第八届
- CSU1119/UVA 12510 Collecting Coins
- 第八届湖南省赛I题 Collecting Coins(BFS)
- 2012年湖南省第八届程序设计大赛 I Collecting Coins(dfs+bfs)
- UVA12510 Collecting Coins
- 利用dfs和bfs的回溯,湖南省第八届省赛Collection Coins
- 湖南省计算机等级考试(二级)题库 第八部分
- 湖南省第八届程序设计竞赛 A
- 湖南省第八届程序设计竞赛 B
- 湖南省第八届程序设计竞赛C
- 湖南省第八届程序设计竞赛D
- 湖南省第八届程序设计竞赛E
- 湖南省第八届程序设计竞赛F
- 湖南省第八届程序设计竞赛G
- 湖南省第八届程序设计竞赛H
- 湖南省第八届程序设计竞赛I
- 湖南省第八届程序设计竞赛J
- iOS 实现UIButton加小红点
- centos7安装mysql
- ZOJ 3452 Doraemon's Stone Game(博弈)
- mapreduce GroupingComparator mapreduce排序规则和分组规则
- 进阶1.JavaScript深入之从原型到原型链
- 湖南省第八届省赛题!!csu1119 Collecting Coins
- C# WinForm的ListView的排序,列标题包括排序三角形
- webpack-生产环境最佳实践(https://webpack.js.org/guides/production/)
- 第三章 MyBatis Mapper 的 XML 配置文件
- spring boot使用fastjson
- 安卓[Android] IOException: open failed: ENOENT (No such file or directory)
- 利用Helm简化Kubernetes应用部署
- spring-boot启动报错【This application has no explicit mapping for /error.....】
- SpringMVC中使用Interceptor拦截器