2495 水叮当的舞步

  

题目描述 Description

  水叮当得到了一块五颜六色的格子形地毯作为生日礼物,更加特别的是,地毯上格子的颜色还能随着踩踏而改变。
  为了讨好她的偶像虹猫,水叮当决定在地毯上跳一支轻盈的舞来卖萌~~~

  地毯上的格子有N行N列,每个格子用一个0~5之间的数字代表它的颜色。
  水叮当可以随意选择一个0~5之间的颜色,然后轻轻地跳动一步,左上角的格子所在的联通块里的所有格子就会变成她选择的那种颜色。这里连通定义为:两个格子有公共边,并且颜色相同。
  由于水叮当是施展轻功来跳舞的,为了不消耗过多的真气,她想知道最少要多少步才能把所有格子的颜色变成一样的。

输入描述 Input Description

  每个测试点包含多组数据。
  每组数据的第一行是一个整数N,表示地摊上的格子有N行N列。
  接下来一个N*N的矩阵,矩阵中的每个数都在0~5之间,描述了每个格子的颜色。
  N=0代表输入的结束。

输出描述 Output Description

  对于每组数据,输出一个整数,表示最少步数。

样例输入 Sample Input

  2
  0 0 
  0 0
  3 
  0 1 2 
  1 1 2
  2 2 1
  0

样例输出 Sample Output

  0
  3

数据范围及提示 Data Size & Hint

  对于30%的数据,N<=5
  对于50%的数据,N<=6
  对于70%的数据,N<=7
  对于100%的数据,N<=8,每个测试点不多于20组数据。

第二组样例解释:
  0 1 2       1 1 2       2 2 2      1 1 1
  1 1 2 --> 1 1 2 --> 2 2 2 --> 1 1 1
  2 2 1       2 2 1       2 2 1      1 1 1


   一开始打了一个四不像的搜索。。只有30..

  后来瞄了一眼题解。。

  发现解题思路还是很神的

  估价函数比较裸:当前剩余颜色数目

  剩下就是怎么搜索了

  把图分为3种颜色

  与(1,1)在一个同色联通块里为1

  在联通块边界但是不与联通块同色为2

  剩下为0

  每次变颜色搜遍整个图然后把与要变颜色相同的且颜色为2的格子拓展一下

  最后都是1的时候退出

  IDA*

  

 #include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm> using namespace std; int n=,map[][],X[]={,,,-},Y[]={,-,,},MAP[][]; bool g[][]; void pre(int x,int y,int col)
{
MAP[x][y]=;
if(x==&&y==)col=map[][];
for(int i=;i<;i++)
{
int xx=x+X[i],yy=y+Y[i];
if(xx<=n&&yy<=n&&xx>=&&yy>=&&MAP[xx][yy]!=)
{
if(map[xx][yy]==col)pre(xx,yy,col);
else MAP[xx][yy]=;
}
}
} /*void ran(int x,int y,int col)
{
for(int i=0;i<4;i++)
{
int xx=x+X[i],yy=y+Y[i];
if(xx<=n&&yy<=n&&xx>=1&&yy>=1&&map[xx][yy]==map[1][1]&&(!(xx+yy==2&&xx==1)))
map[xx][yy]=col,ran(xx,yy,col);
}
}*/ int get()
{
int res[]={},nu=;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(!res[map[i][j]] && MAP[i][j]!=)
{
res[map[i][j]]=;
nu++;
}
return nu;
} void dfs(int x,int y,int col)
{
MAP[x][y]=;
for(int i=;i<;i++)
{
int xx=X[i]+x,yy=y+Y[i];
if(xx<=n&&yy<=n&&xx>=&&yy>=&&MAP[xx][yy]!=)
{
if(map[xx][yy]==col)dfs(xx,yy,col);
else MAP[xx][yy]=;
}
}
} bool fill(int col)
{
int ret=;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(MAP[i][j]==&&map[i][j]==col)
{
ret++;
dfs(i,j,col);
}
return ret;
} bool IDA(int k)
{
/*memset(g,0,sizeof(g));
int stop=find(1,1,0),ctrl=0,temp[11][11];
if(!stop)return 1;
else if(!k)return 0;
for(int i=0;i<=5;i++)
if(i!=map[1][1]&&(stop&(1<<i))!=0)
{
memcpy(temp,map,sizeof(map));
ran(1,1,i);
map[1][1]=i;
ctrl=IDA(k-1);
if(!ctrl)memcpy(map,temp,sizeof(temp));
else return 1;
}
return 0;*/
int nu=get();
if(nu==)return ;
else if(k+<nu)return ;
int temp[][]={};
for(int i=;i<=;i++)
{
memcpy(temp,MAP,sizeof(MAP));
if(fill(i) && IDA(k-))return ;
memcpy(MAP,temp,sizeof(temp));
}
return ;
} int main()
{
while()
{
scanf("%d",&n);
if(!n)break;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
scanf("%d",&map[i][j]);
memset(MAP,,sizeof(MAP));
pre(,,map[][]);
for(int i=;i<=n*n;i++)
if(IDA(i)){printf("%d\n",i);break;}
}
return ;
}

  

 

最新文章

  1. EF架构~真正被封装的排序方法,支持多列排序
  2. 利用JSDOC快速生成注释文档,非常棒。
  3. JeeSite环境搭建及运行和打包(master20161117)
  4. 包含块、层叠上下文、BFC
  5. bash shell——与if条件相关的参数意义
  6. Java操作属性文件,支持新增或更新多个属性
  7. pack布局
  8. Android动画之二:View Animation
  9. Php 关于构造函数
  10. BUGKUctf-web-writeup
  11. ionic 最简单的路由形式,头部固定,下面tab切换-------一个简单的单页切换起飞了
  12. 创建类似于Oracle中decode的函数
  13. MySQL EXPLAIN 命令: 查看查询执行计划
  14. Centos 6.8 配置mysql数据库主从同步
  15. Homework 2.0
  16. [HDFS_add_2] SecondaryNameNode 滚动 NameNode 数据流程
  17. 如何理解&lt;base href=&quot;&lt;%=basePath%&gt;&quot;
  18. 回文字符串 NYOJ
  19. taro 事件处理
  20. 理解Golang包导入

热门文章

  1. Silverlight中本地化的实现(语言切换)
  2. jQuery cookie插件保存用户登陆信息
  3. apache2下部署node.js应用程序
  4. 复习URLHttpConnection方式GET,POST方式链接网络解析uri
  5. tcp,第一个例子,客户端,服务端
  6. mssql 置疑的处理
  7. delphi中表示跳出的有break,continue, exit,abort, halt, runerror
  8. Keil的使用方法 - 常用功能(二)
  9. Oracle 11g Windows 迁移至 Linux
  10. hdu 2578 Dating with girls(1)