「Poetize5」水叮当的舞步
Description
水叮当得到了一块五颜六色的格子形地毯作为生日礼物,更加特别的是,地毯上格子的颜色还能随着踩踏而改变。
为了讨好她的偶像虹猫,水叮当决定在地毯上跳一支轻盈的舞来卖萌~~~
地毯上的格子有N行N列,每个格子用一个0~5之间的数字代表它的颜色。
水叮当可以随意选择一个0~5之间的颜色,然后轻轻地跳动一步,左上角的格子所在的联通块里的所有格子就会变成她选择的那种颜色。这里连通定义为:两个格子有公共边,并且颜色相同。
由于水叮当是施展轻功来跳舞的,为了不消耗过多的真气,她想知道最少要多少步才能把所有格子的颜色变成一样的。
题解:
我来当搬运工。。。
类型:IDA* (迭代加深启发式搜索)
方法一:
枚举每次选取了哪种颜色,然后找出左上角的格子所在的联通块,改变颜色。
为了避免来回改变、搜索深度过大,采用迭代加深的dfs限制搜索步数。
迭代加深也就是,依次限制搜索深度为0、1、2、3……进行搜索,搜索过程中发现深度超过限制就马上退出。只要搜索成功就找到了答案,也可以立即退出。
期望得分:0~10分。
方法二:
加入一个小剪枝:如果改变颜色后,左上角格子所在的联通块大小没有改变,可以剪枝。这样可以避免来回往复地搜索。
期望得分:10~20分。
方法三:
采用IDA*算法,设计估价函数。可以发现如果当前矩阵中除了左上角的联通块之外,共有M种颜色,那么还需要的步数不小于M。因此如果当前搜索深度+估价函数的值>深度限制,可以回溯。
期望得分:50~70分。
方法四:
我们可以发现,每次寻找左上角的格子所在的联通块耗费的时间常数巨大。因此我们在这里寻求突破。
我们引入一个N*N的v数组。左上角的格子所在的联通块里的格子标记为1。左上角联通块周围一圈格子标记为2,其它格子标记为0。如果某次选择了颜色c,我们只需要找出标记为2并且颜色为c的格子,向四周扩展,并相应地修改v标记,就可以不断扩大标记为1的区域,最终如果所有格子标记都是1,那么显然找到了答案。
代码:
#include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #include<iostream> #include<vector> #include<map> #include<set> #include<queue> #include<string> #define inf 1000000000 #define maxn 500+100 #define maxm 500+100 #define eps 1e-10 #define ll long long #define pa pair<int,int> #define for0(i,n) for(int i=0;i<=(n);i++) #define for1(i,n) for(int i=1;i<=(n);i++) #define for2(i,x,y) for(int i=(x);i<=(y);i++) #define for3(i,x,y) for(int i=(x);i>=(y);i--) #define mod 1000000007 using namespace std; inline int read() { int x=,f=;char ch=getchar(); while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();} while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();} return x*f; }
const int dx[]={-,,,},dy[]={,-,,};
int a[][],v[][],f[],n,ID;
inline int left()
{
int tmp=;
memset(f,,sizeof(f));
for1(i,n)for1(j,n)
if(!f[a[i][j]]&&v[i][j]!=){f[a[i][j]]=;tmp++;}
return tmp;
}
inline void dfs(int x,int y,int c)
{
v[x][y]=;
for0(i,)
{
int xx=x+dx[i],yy=y+dy[i];
if(xx<||xx>n||yy<||yy>n||v[xx][yy]==)continue;
v[xx][yy]=;
if(a[xx][yy]==c)dfs(xx,yy,c);
}
}
inline int fill(int c)
{
int tmp=;
for1(i,n)for1(j,n)
if(a[i][j]==c&&v[i][j]==)
{
tmp++;
dfs(i,j,c);
}
return tmp;
}
inline bool IDA(int dep)
{
int g=left();
if(dep+g>ID)return ;
if(!g)return ;
int rec[][];
for0(i,)
{
memcpy(rec,v,sizeof(v));
if(fill(i)&&IDA(dep+))return ;
memcpy(v,rec,sizeof(v));
}
return ;
} int main() { freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); while(cin>>n&&n)
{
memset(a,,sizeof(a));
memset(v,,sizeof(v));
for1(i,n)for1(j,n)a[i][j]=read();
dfs(,,a[][]);
for(ID=;;ID++)
if(IDA())break;
printf("%d\n",ID);
} return ; }
「Poetize5」水叮当的舞步的更多相关文章
- bzoj3041 水叮当的舞步 IDA*
水叮当的舞步 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 230 Solved: 107[Submit][Status][Discuss] Des ...
- BZOJ 3041 水叮当的舞步
3041: 水叮当的舞步 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 120 Solved: 67[Submit][Status][Discuss ...
- codevs 2495 水叮当的舞步
题目链接:水叮当的舞步 我现在开始发题目链接了(主要还是因为懒得整理题面)-- 这道题一开始是看到MashiroSky在写,于是我也开始写这道题了(说白了就是狙击他)-- 这道题看到这么小的范围当然给 ...
- 【IDA*】codevs 2495:水叮当的舞步
2495 水叮当的舞步 题目描述 Description 水叮当得到了一块五颜六色的格子形地毯作为生日礼物,更加特别的是,地毯上格子的颜色还能随着踩踏而改变. 为了讨好她的偶像虹猫,水叮当决定在地毯上 ...
- bzoj 3041: 水叮当的舞步 迭代加深搜索 && NOIP RP++
3041: 水叮当的舞步 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 72 Solved: 44[Submit][Status] Descript ...
- 【BZOJ3041】水叮当的舞步 迭代深搜IDA*
[BZOJ3041]水叮当的舞步 Description 水叮当得到了一块五颜六色的格子形地毯作为生日礼物,更加特别的是,地毯上格子的颜色还能随着踩踏而改变.为了讨好她的偶像虹猫,水叮当决定在地毯上跳 ...
- [codevs2495]水叮当的舞步
[codevs2495]水叮当的舞步 试题描述 水叮当得到了一块五颜六色的格子形地毯作为生日礼物,更加特别的是,地毯上格子的颜色还能随着踩踏而改变. 为了讨好她的偶像虹猫,水叮当决定在地毯上跳一支轻盈 ...
- Bzoj3041 水叮当的舞步
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 132 Solved: 75 Description 水叮当得到了一块五颜六色的格子形地毯作为生日礼物 ...
- 【wikioi】2495 水叮当的舞步(IDA*)
http://wikioi.com/problem/2495/ 这题我还是看题解啊囧.(搜索实在太弱.完全没想到A*,还有看题的时候想错了,.,- -) 好吧,估价还是那么的简单,判断颜色不同的数目即 ...
随机推荐
- 浏览器中JavaScript执行原理
本章我们讨论javascript在浏览器中是如果工作的,包括:下载.解析.执行的全过程.javascript的这些讨人嫌的地方我们是知道的: i.需要串行下载 ii.需要解析 iii.需要串行执行 而 ...
- 2 - SQL Server 2008 之 使用SQL语句为现有表添加约束条件
上一节讲的是直接在创建表的时候添加条件约束,但是有时候是在表格创建完毕之后,再添加条件约束的,那么这个又该如何实现? 其实,跟上一节所写的SQL代码,很多是相同的,只是使用了修改表的ALTER关键字及 ...
- java取得整数部分 代码
Pattern p1 = Pattern.compile("[0-9]*"); Matcher m1 = p1.matcher("100.0"); boolea ...
- IDL计算儒略日
遥感数据还有一些文章中使用数据的时候,经常使用儒略日(Julian day),即计算该天是一年中的第几天.正好有时间,就用IDL写了段儿小代码,方便使用. ;+ ; :Author: caoz ...
- windows 环境下mysql 如何修改root密码
windows 环境下mysql 如何修改root密码 以windows为例: 无法开启服务,将mysql更目录下的data文件夹清空,然后调用 mysqld --initialize 开启mysql ...
- 浅谈inline-block
一.区分block,inline,inline-block 1.block block元素会独占一行,多个block元素会各自新起一行.默认情况下,block元素宽度自动填满其父元素宽度. block ...
- 一次项目中用到的php函数总结
最近做的一个项目,我把做的过程中用到的php函数总结一下.以后遇到类似的不用百度,直接看自己总结的就好了.都是一些简单基础的函数,随手记下.方便以后学习. 1.array_sum() 返回数组中的所有 ...
- Activity的几种启动跳转方式
一.显示调用方法 •Intent intent=new Intent(this,OtherActivity.class); //方法1 •Intent intent2=new Intent(); • ...
- JAVA JDK 1.6 API中文版.CHM打开chm提示,“ 已取消到该网页的导航”
JAVA JDK 1.6 API中文版.CHM打开chm提示,“ 已取消到该网页的导航” silent fish 装了win7后,打开chm文件,发现很多在xp系统打开正常的chm文件竟然出现问题, ...
- 打造属于前端的Uri解析器
今天和大家一起讨论一下如何打造一个属于前端的url参数解析器.如果你是一个Web开发工程师,如果你了解过后端开发语言,譬如:PHP,Java等,那么你对下面的代码应该不会陌生: $kw = $_GET ...