隐藏页面特效

BZOJ 3041 水叮当的舞步

 

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=0,f=1; register char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); return ch-'0'; } const int dx[]={0,0,1,-1}; const int dy[]={1,-1,0,0}; const int N=9; int n,g[N][N],a[N][N]; bool flag,vis[N][N],mark[N]; inline void calc(int &c){ memset(mark,0,sizeof mark); c=0; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(!mark[a[i][j]]){ mark[a[i][j]]=1; c++; } } } } void go(int x,int y,int c,int r){ a[x][y]=r; vis[x][y]=1; for(int i=0;i<4;i++){ int nx=x+dx[i]; int ny=y+dy[i]; if(!vis[nx][ny]&&nx>0&&nx<=n&&ny>0&&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]=1; for(int i=0;i<4;i++){ int nx=x+dx[i]; int ny=y+dy[i]; if(!vis[nx][ny]&&nx>0&&nx<=n&&ny>0&&ny<=n){ if(a[nx][ny]==c) get_round(nx,ny,c,round); else if(!round[a[nx][ny]]) round[a[nx][ny]]=1; } } } void dfs(int now,int sum){ if(flag) return ; int C; calc(C); if(now==sum){ if(C==1) flag=1; return ; } if(now+C-1>sum) return ; memset(vis,0,sizeof vis); int round[N]={0}; get_round(1,1,a[1][1],round); for(int i=0;i<=5;i++){ if(i==a[1][1]||!round[i]) continue; int back[N][N]; memcpy(back,a,sizeof a); memset(vis,0,sizeof vis); go(1,1,a[1][1],i); if(flag) return ; dfs(now+1,sum); memcpy(a,back,sizeof back); } } int main(){ for(;;){ n=read(); if(!n) break; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ g[i][j]=read(); } } int ans=0; for(int k=0;k<=16;k++){ memcpy(a,g,sizeof g); flag=0; dfs(0,k); if(flag){ ans=k; break; } } printf("%d\n",ans); } return 0; }

 


__EOF__

本文作者shenben
本文链接https://www.cnblogs.com/shenben/p/5823304.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   神犇(shenben)  阅读(564)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示