3041: 水叮当的舞步

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 120  Solved: 67
[Submit][Status][Discuss]

Description

水叮当得到了一块五颜六色的格子形地毯作为生日礼物,更加特别的是,地毯上格子的颜色还能随着踩踏而改变。
为了讨好她的偶像虹猫,水叮当决定在地毯上跳一支轻盈的舞来卖萌~~~
地毯上的格子有N行N列,每个格子用一个0~5之间的数字代表它的颜色。
水叮当可以随意选择一个0~5之间的颜色,然后轻轻地跳动一步,左上角的格子所在的联通块里的所有格子就会变成她选择的那种颜色。这里连通定义为:两个格子有公共边,并且颜色相同。
由于水叮当是施展轻功来跳舞的,为了不消耗过多的真气,她想知道最少要多少步才能把所有格子的颜色变成一样的。

Input

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

Output

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

Sample Input

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

Sample Output

0
3

对于100%的数据,N<=8,每个测试点不多于20组数据。

HINT

 

Source

题解:

IDA*

比较简单的A* 估价函数很简单就是除了左上角的联通快之外的不同的个数
加上迭代,dfs就好了

10s时间很宽裕

AC代码:

(codevs80-90分)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
inline const int read(){
register int x=,f=;
register char ch=getchar();
while(ch<''||ch>'') ch=getchar();
return ch-'';
}
const int dx[]={,,,-};
const int dy[]={,-,,};
const int N=;
int n,g[N][N],a[N][N];
bool flag,vis[N][N],mark[N];
inline void calc(int &c){
memset(mark,,sizeof mark);
c=;
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
if(!mark[a[i][j]]){
mark[a[i][j]]=;
c++;
}
}
}
}
void go(int x,int y,int c,int r){
a[x][y]=r;
vis[x][y]=;
for(int i=;i<;i++){
int nx=x+dx[i];
int ny=y+dy[i];
if(!vis[nx][ny]&&nx>&&nx<=n&&ny>&&ny<=n&&a[nx][ny]==c){
go(nx,ny,c,r);
}
}
}
void get_round(int x,int y,int c,int round[]){
vis[x][y]=;
for(int i=;i<;i++){
int nx=x+dx[i];
int ny=y+dy[i];
if(!vis[nx][ny]&&nx>&&nx<=n&&ny>&&ny<=n){
if(a[nx][ny]==c) get_round(nx,ny,c,round);
else if(!round[a[nx][ny]]) round[a[nx][ny]]=;
}
}
}
void dfs(int now,int sum){
if(flag) return ;
int C;
calc(C);
if(now==sum){
if(C==) flag=;
return ;
}
if(now+C->sum) return ;
memset(vis,,sizeof vis);
int round[N]={};
get_round(,,a[][],round);
for(int i=;i<=;i++){
if(i==a[][]||!round[i]) continue;
int back[N][N];
memcpy(back,a,sizeof a);
memset(vis,,sizeof vis);
go(,,a[][],i);
if(flag) return ;
dfs(now+,sum);
memcpy(a,back,sizeof back);
}
}
int main(){
for(;;){
n=read();
if(!n) break;
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
g[i][j]=read();
}
}
int ans=;
for(int k=;k<=;k++){
memcpy(a,g,sizeof g);
flag=;
dfs(,k);
if(flag){
ans=k;
break;
}
}
printf("%d\n",ans);
}
return ;
}

最新文章

  1. 【原】SDWebImage源码阅读(四)
  2. 配置高可用的Hadoop平台
  3. Base Enum Properties [AX 2012]
  4. Loadrunner基础:Loadrunner Controller基本概念和使用
  5. 以不同用户身份运行程序,/savecred只需要输入一次密码(GetTokenByName取得EXPLORER.EXE的令牌,然后调用CreateProcessAsUser,而且使用LoadUserProfile解决另存文件的问题)good
  6. elasticsearch 搜索不支持单词的部分进行匹配
  7. 普林斯顿大学算法课 Algorithm Part I Week 3 求第K大数 Selection
  8. kindeditor图片上传 struts2实现
  9. 听翁恺老师mooc笔记(4)--指针的应用场景
  10. ButterKnife的使用详解
  11. Spring Boot/Spring Cloud
  12. sring引入mybatis
  13. 牛客网练习赛7-B-购物
  14. 点击button后刷新了页面
  15. python ---16 初识面向对象
  16. 012 - jstat命令查看jvm的GC情况 | jvm
  17. JSON-java
  18. Oracle自定义函数和存储过程示例,自定义函数与存储过程区别
  19. 【monkeyrunner】monkeyrunner脚本录制和回放
  20. boa 服务的启动

热门文章

  1. swiper 3D 覆盖流的使用方法
  2. Servlet中的几个重要的对象(转)
  3. Shiro框架 (原理分析与简单实现)
  4. [Python3网络爬虫开发实战] 2.4-会话和Cookies
  5. Spider-scrapy日志处理
  6. Win8系统下MT4不能添加指标无法找到技术指标
  7. STM32——通用定时器基本定时功能
  8. IOC&amp;DI
  9. 用mycat做读写分离:基于 MySQL主从复制
  10. 587. Erect the Fence