【NOIP2016提高A组模拟】配对游戏
来源:互联网 发布:nx车铣复合加工编程书 编辑:程序博客网 时间:2024/06/05 07:54
Description
流行的跳棋游戏是在一个有m*n个方格的长方形棋盘上玩的。棋盘起初全部被动物或障碍物占满了。在一个方格中,‘X’表示一个障碍物,一个‘0’~‘9’的个位数字表示一个不同种类的动物,相同的个位数字表示相同种类的动物。一对动物只有当它们属于同一种类时才可以被消去。消去之后,他们所占的方格就成为空方格,直到游戏结束。要消去一对动物的前提条件是:这对候选动物所在的方格必须相邻,或它们之间存在一条通路。棋盘上一个方格只和其上下左右的方格相邻。一条通路是由一串相邻的空方格组成。路的长度则是通路中空方格的数目。你要输出可被消去的动物的最多对数,以及在此操作过程中,最小的通路长度总和。
例1 如下的一个3*4棋盘:
两个种类为“1”的动物可以被消去,因为它们相邻,通路的长度是0。在这一步骤之后,存在一条在两个种类为“0”的动物间的长度为2的通路,所以这两个动物也可以被消去。要消去这2对动物,通路的长度总和是 0+2=2。这也是最小的通路长度总和,因为这是唯一一个消去这2对动物的方法。所以答案是 2 2。
例2 如下的一个4*1棋盘:
如果我们先消去正中间的两个种类为“9”的动物,然后消去最上面和最下面的两个种类为“9”的动物,则累计通路长度为 0+2=2。但是,我们可以先消去最顶上的两个,然后再消去最底下的两个。同样也消去了2对动物,但通路长度总和是 0+0=0。很明显,长为0的通路长度总和是最短的,答案应是 2 0。
Solution
这是有NOIP第三题的风范,要不是没有对拍,有可能这场比赛就AK了。
我打了三个dfs。
第一个dfs:处理每个块的每个颜色,分别放进桶里
第二个dfs:把桶里的元素暴力的两两匹配(回溯)
第三个dfs:因为桶里的两个元素,要判断是否能互相到达,还要判断两两的最短路,这就是需要第三个dfs
然后三个结合起来,打一些优化(超过答案了就不搜了),然后就能过了。
Code
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;const int fang[4][2]={1,0,0,1,-1,0,0,-1};int i,j,k,l,t,n,m,ans,zhi,ans1,yi,er,xo,yo;char s[10][10];int a[10][10],sex[10][100],sey[10][100],sen[10],cnt,ci,dz[10][10],f[10][10];bool bz[10][10],az[10][10];void dfs(int x,int y){ int i,c,d; sen[a[x][y]]++; sex[a[x][y]][sen[a[x][y]]]=x; sey[a[x][y]][sen[a[x][y]]]=y; az[x][y]=1; dz[x][y]=ci; fo(i,0,3){ c=fang[i][0]+x,d=fang[i][1]+y; if(c<1||c>n||d<1||d>m||a[c][d]==-1||az[c][d])continue; dfs(c,d); }}void dfs1(int x,int y,int xx,int yy,int z){ int i,c,d; if(zhi&&z>=zhi)return; if(x==xx&&y==yy){ if(!zhi)zhi=z; else zhi=min(zhi,z); return; } f[x][y]=z; fo(i,0,3){ cnt++; c=fang[i][0]+x,d=fang[i][1]+y; if(c<1||c>n||d<1||d>m||a[c][d]==-1||z+1>=f[c][d]||(a[c][d]!=-2&&(c!=xx||d!=yy)))continue; dfs1(c,d,xx,yy,z+1); }}void dfs2(int x,int y){ int i,j,k,c=0; if(x>yi)yi=x,er=y; else if(y>=er)return; else if(x==yi){ if(y<er)er=y; else return; } if(cnt>=10000000)return; fo(k,0,9){ fo(i,1,sen[k]){ if(a[sex[k][i]][sey[k][i]]==-2)continue; fo(j,i+1,sen[k]){ if(a[sex[k][j]][sey[k][j]]==-2)continue; zhi=0;memset(bz,0,sizeof(bz));memset(f,127,sizeof(f)); f[sex[k][i]][sey[k][i]]=0; cnt+=11; dfs1(sex[k][i],sey[k][i],sex[k][j],sey[k][j],0); if(zhi){ a[sex[k][i]][sey[k][i]]=-2,a[sex[k][j]][sey[k][j]]=-2; dfs2(x+1,y+zhi-1); a[sex[k][i]][sey[k][i]]=k,a[sex[k][j]][sey[k][j]]=k; } } } }}int main(){// freopen("fan.in","r",stdin);// freopen("fan.out","w",stdout); freopen("pair.in","r",stdin); freopen("pair.out","w",stdout); scanf("%d%d",&n,&m); fo(i,1,n){ scanf("%s",s[i]+1); fo(j,1,m){ if(s[i][j]=='X')a[i][j]=-1;else a[i][j]=s[i][j]-'0'; } } fo(i,1,n)fo(j,1,m){ if(a[i][j]!=-1&&!az[i][j]){ ci++; memset(sen,0,sizeof(sen)); dfs(i,j); yi=0; fo(k,0,9)fo(i,1,sen[k]/2) er+=abs(sex[k][i]-sex[k][sen[k]-i+1])+abs(sey[k][i]-sey[k][sen[k]-i+1]); cnt=0; dfs2(0,0); ans+=yi,ans1+=er; } } printf("%d %d",ans,ans1);}
- 【NOIP2016提高A组模拟】配对游戏
- 【JZOJ4824】【NOIP2016提高A组集训第1场10.29】配对游戏
- NOIP2016提高A组集训第1场 【JZOJ4824】配对游戏
- 【NOIP2016提高A组集训第1场10.29】配对游戏
- JZOJ 4824. 【NOIP2016提高A组集训第1场10.29】配对游戏
- 【NOIP2016提高A组模拟7.15】立方体
- 计数【NOIP2016提高A组模拟7.15】
- 【NOIP2016提高A组模拟7.17】寻找
- 【NOIP2016提高A组模拟7.17】寻找
- 【NOIP2016提高A组模拟7.17】锦标赛
- 【NOIP2016提高A组模拟7.17】锦标赛
- 【NOIP2016提高A组模拟7.17】锦标赛
- 【NOIP2016提高A组模拟7.15】修路
- 【NOIP2016提高A组模拟7.15】计数
- 寻找【NOIP2016提高A组模拟7.17】
- 锦标赛【NOIP2016提高A组模拟7.17】
- 【NOIP2016提高A组模拟8.14】传送带
- 【NOIP2016提高A组模拟8.14】传送带
- 数据结构——队列的链式存储结构以及实现
- Android 录音和摄像头权限适配
- POJ 2457 BFS
- 【codeforces 27 E】【反素数】【给一个数n,求一个最小的正整数,使得它的因子个数为n】
- 面试——读写锁ReadWriteLock
- 【NOIP2016提高A组模拟】配对游戏
- js 选择器兼容
- KoaHub.js是基于 Koa.js 平台的 Node.js web 快速开发框架
- Go语言安装与liteIDE配置
- [C#]DataTable和DataSet有什么区别
- python中os.system调用exe文件问题
- C文件读写函数介绍(转)
- java之泛型(Generic)
- Microsoft .NET Framework 各个版本之间的关系?如何安装2.0,3.0,4.0?向下兼容?