【NOIP2016提高A组集训第1场10.29】配对游戏
题目
流行的跳棋游戏是在一个有mn个方格的长方形棋盘上玩的。棋盘起初全部被动物或障碍物占满了。在一个方格中,‘X'表示一个障碍物,一个‘0’~‘9’的个位数字表示一个不同种类的动物,相同的个位数字表示相同种类的动物。一对动物只有当它们属于同一种类时才可以被消去。消去之后,他们所占的方格就成为空方格,直到游戏结束。要消去一对动物的前提条件是:这对候选动物所在的方格必须相邻,或它们之间存在一条通路。棋盘上一个方格只和其上下左右的方格相邻。一条通路是由一串相邻的空方格组成。路的长度则是通路中空方格的数目。你要输出可被消去的动物的最多对数,以及在此操作过程中,最小的通路长度总和。
例1 如下的一个34棋盘:
两个种类为“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。
分析
暴力,加个判重。
因为只有25个格子,将每个格子是否消掉化成二进制状态,
记录这个状态的最优答案。
用正确率换时间,随便坑坑就过了。
还跑到特别快,我自己都惊呆了。
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const int maxlongint=2147483647;
const int mo=1000000007;
const int N=7;
using namespace std;
int c[11][37][2],a[N][N],ans,n,m,ans1;
short int hash[33554532][2];
int zz[4][2]=
{
{0,1},
{1,0},
{0,-1},
{-1,0}
};
inline int dg1(int b[N][N],int x,int y,int v,int dis[N][N])
{
for(int i=0;i<=3;i++)
{
int xx=zz[i][0]+x,yy=zz[i][1]+y;
if(xx<1 || xx>n || yy<1 || yy>m) continue;
if(b[xx][yy]==11)
{
if(dis[xx][yy]>dis[x][y]+1) dis[xx][yy]=dis[x][y]+1,dg1(b,xx,yy,v,dis);
}
else
if(b[xx][yy]==v)
{
dis[xx][yy]=min(dis[x][y]+1,dis[xx][yy]);
}
}
}
inline int dg(int b[N][N],int v,int sum)
{
int num=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(b[i][j] && b[i][j]!=11) num+=1<<((i-1)*m+j-1);
}
if(!hash[num][0])
{
hash[num][0]=sum;
hash[num][1]=v;
}
else
{
if(hash[num][0]>sum) return 0;
if(hash[num][0]==sum && hash[num][1]<=v) return 0;
hash[num][0]=sum;
hash[num][1]=v;
}
bool q=true;
int dis[N][N],mn;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(b[i][j] && b[i][j]!=11)
{
memset(dis,43,sizeof(dis));
dis[i][j]=0;
dg1(b,i,j,b[i][j],dis);
int g=b[i][j];
mn=maxlongint;
for(int k=1;k<=c[g][0][0]-1;k++)
for(int l=k+1;l<=c[g][0][0];l++)
{
if(dis[c[g][k][0]][c[g][k][1]]>dis[c[g][l][0]][c[g][l][1]])
{
int o=c[g][k][0];
c[g][k][0]=c[g][l][0];
c[g][l][0]=o;
o=c[g][k][1];
c[g][k][1]=c[g][l][1];
c[g][l][1]=o;
}
}
for(int k=1;k<=c[g][0][0];k++)
if(dis[c[g][k][0]][c[g][k][1]]!=dis[0][0] && b[c[g][k][0]][c[g][k][1]]==b[i][j] && (i!=c[g][k][0] || j!=c[g][k][1]))
{
b[i][j]=b[c[g][k][0]][c[g][k][1]]=11;
dg(b,v+dis[c[g][k][0]][c[g][k][1]]-1,sum+1);
q=false;
b[i][j]=b[c[g][k][0]][c[g][k][1]]=g;
}
}
}
if(q)
{
if(sum>ans)
{
ans=sum;
ans1=v;
}
else
if(sum==ans && ans1>v) ans1=v;
return 0;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
char ch=getchar();
while((ch<'0' || ch>'9') && ch!='X') ch=getchar();
if(ch>='0' && ch<='9')
{
a[i][j]=ch-47;
c[ch-47][0][0]++;
c[ch-47][c[ch-47][0][0]][0]=i;
c[ch-47][c[ch-47][0][0]][1]=j;
}
}
ans=0;
ans1=maxlongint;
dg(a,0,0);
printf("%d %d",ans,ans1);
}
【NOIP2016提高A组集训第1场10.29】配对游戏的更多相关文章
- 【JZOJ4824】【NOIP2016提高A组集训第1场10.29】配对游戏
题目描述 流行的跳棋游戏是在一个有m*n个方格的长方形棋盘上玩的.棋盘起初全部被动物或障碍物占满了.在一个方格中,'X'表示一个障碍物,一个'0'-'9'的个位数字表示一个不同种类的动物,相同的个位数 ...
- 【NOIP2016提高A组集训第1场10.29】完美标号
题目 给定M个二元组(A_i, B_i),求X_1, ..., X_N满足:对于任意(A_i, B_i),有|X_{A_i} - X_{B_i}| = 1成立. 分析 显然,对于二元组(x,y),X_ ...
- 【NOIP2016提高A组集训第3场10.31】高维宇宙
题解 分析 因为只有奇数和偶数配对才有可能得出质数, 暴力求出每一对\(a_i+a_j\)为质数,将其中的奇数想偶数连一条边. 二分图匹配,匈牙利算法. #include <cmath> ...
- 【JZOJ4831】【NOIP2016提高A组集训第3场10.31】方程式
题目描述 数据范围 解法 枚举根之后,使用大除法. 代码 #include<stdio.h> #include<iostream> #include<string.h&g ...
- 【JZOJ4832】【NOIP2016提高A组集训第3场10.31】高维宇宙
题目描述 数据范围 解法 由于大于4的素数只有可能由奇数和偶数的和得出. 所以根据数的奇偶性可以分出两类数奇数和偶数. 奇数之间不会相互匹配,偶数之间也不会相互匹配. 那么原问题转化为二分图最大匹配. ...
- 【JZOJ4833】【NOIP2016提高A组集训第3场10.31】Mahjong
题目描述 解法 搜索. 代码 #include<stdio.h> #include<iostream> #include<string.h> #include< ...
- JZOJ 【NOIP2016提高A组集训第16场11.15】兔子
JZOJ [NOIP2016提高A组集训第16场11.15]兔子 题目 Description 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3 ...
- JZOJ 【NOIP2016提高A组集训第16场11.15】SJR的直线
JZOJ [NOIP2016提高A组集训第16场11.15]SJR的直线 题目 Description Input Output Sample Input 6 0 1 0 -5 3 0 -5 -2 2 ...
- 【NOIP2016提高A组集训第4场11.1】平衡的子集
题目 夏令营有N个人,每个人的力气为M(i).请大家从这N个人中选出若干人,如果这些人可以分成两组且两组力气之和完全相等,则称为一个合法的选法,问有多少种合法的选法? 分析 如果暴力枚举每个人被分到哪 ...
随机推荐
- oracle导入导出常见问题及解决方案
一.导出 1.导出命令 exp 用户名/密码@实例名 file=路径 2.出现问题:空表不能导出, 解决方案: --查找空表 SELECT TABLE_NAME FROM USER_TAB ...
- 【HANA系列】SAP HANA Studio代码提示设置方法
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA Studio代 ...
- 【ABAP系列】SAP BOM反查
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP BOM反查 前言部分 ...
- cocos2dx[3.2](11) 新事件分发机制
在2.x中处理事件需要用到委托代理(delegate),相信学过2.x的触摸事件的同学,都知道创建和移除的流程十分繁琐. 而在3.x中由于加入了C++11的特性,而对事件的分发机制通过事件分发器Eve ...
- 【神经网络与深度学习】学习笔记:AlexNet&Imagenet学习笔记
学习笔记:AlexNet&Imagenet学习笔记 ImageNet(http://www.image-net.org)是李菲菲组的图像库,和WordNet 可以结合使用 (毕业于Caltec ...
- 【DSP开发】【VS开发】MUX和DEMUX的含义
MUX和DEMUX Mux 是 Multiplex 的缩写,意为"多路传输",其实就是"混流"."封装"的意思,与"合成" ...
- 微信小程序开发(二)----- 云开发
1.概念 微信小程序的云开发是腾讯云与微信团队深度合作推出的一个全新的小程序的解决方案,它提供了云函数.云数据库与云存储这三大基础能力支持,随着云开发的出现,小程序的开发者可以将服务端的部署和运营的环 ...
- 【洛谷P1886】滑动窗口——单调队列
没想到啊没想到,时隔两个月,我单调队列又懵了…… 调了一个小时,最后错在快读,啊!!!!(不过洛谷讨论真好啊,感谢大佬!) 考前就不推新东西了,好好写写那些学过的东西 题目点这里(我就不粘了自己点一下 ...
- python3—廖雪峰之练习(一)
变量练习 小明的成绩从去年的72分提升到今年的85分,请计算小明成绩提升的百分点.并用 字符串格式化显示出'xx.x%',只保留小数点后一位: s1 = 72 s2 = 85 r = (85-72)/ ...
- openCV 二 图像处理
官网:https://docs.opencv.org/3.2.0/df/d9d/tutorial_py_colorspaces.html 改变颜色空间 本教程颜色空间转换:BGR ↔ Gray and ...