【codevs2495】 水叮当的舞步

http://codevs.cn/problem/2495/ (题目链接)

题意

  给出一个N*N的矩阵,其中元素有5种颜色,每次可以将左上角元素所在的连通块更换一种颜色,连通块指相邻并且颜色相同的元素在同一连通块内。问最少改变几次颜色使得所有元素颜色相同。

Solution

  刚开始打了个迭代加深,get了20分。。。考虑如何对它进行优化。

  一个很显然的优化就是染色的时候,只对连通块周围的属于连通块的一圈元素进行扩展,并保存下染色后新的外圈元素。

  可是仅仅这样还是不够,只能get50分。

  考虑A*,如何构造估价函数呢。显然,如果剩下的不属于连通块的元素有cnt种不同的颜色,那么至少还需要染色cnt次,那么如果cnt+当前步数>枚举深度d,显然这样走下去不会出答案,直接退出即可。

细节

  细节有点恶心,刚开始我用的bfs实现染色操作,然后回溯还有各种不好做的操作,就直接翻了题解。。真是很优美。。

代码

// codevs2495
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define LL long long
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;

int xx[4]={0,0,-1,1};
int yy[4]={1,-1,0,0};
int a[10][10],vis[10][10],e[6];
int n,flag,d;

void color(int x,int y,int col) {
	vis[x][y]=1;
	for (int i=0;i<4;i++) {
		int nx=x+xx[i],ny=y+yy[i];
		if (nx<1 || nx>n || ny<1 || ny>n || vis[nx][ny]==1) continue;
		vis[nx][ny]=2;
		if (a[nx][ny]==col) color(nx,ny,col);
	}
}
int eva(int s) {
	int cnt=0;
	memset(e,0,sizeof(e));
	for (int i=1;i<=n;i++)
		for (int j=1;j<=n;j++)
			if (vis[i][j]!=1 && !e[a[i][j]]) e[a[i][j]]=1,cnt++;
	return cnt;
}
bool judge(int col) {
	int tmp=0;
	for (int i=1;i<=n;i++)
		for (int j=1;j<=n;j++) if (a[i][j]==col && vis[i][j]==2) {
				tmp++;
				color(i,j,col);
			}
	return tmp>0;
}
void search(int s) {
	int tmp=eva(s),t[10][10];
	if (tmp==0) {flag=1;return;}
	else if (tmp+s>d) return;
	for (int i=0;i<=5;i++) {
		memcpy(t,vis,sizeof(t));
		if (judge(i)) search(s+1);
		memcpy(vis,t,sizeof(vis));
		if (flag) return;
	}
}
int main() {
	while (scanf("%d",&n)!=EOF && n) {
		flag=0;memset(vis,0,sizeof(vis));
		for (int i=1;i<=n;i++)
			for (int j=1;j<=n;j++) scanf("%d",&a[i][j]);
		color(1,1,a[1][1]);
		for (d=0;d>=0;d++) {
			search(0);
			if (flag) {printf("%d\n",d);break;}
		}
	}
	return 0;
}

  

时间: 2025-01-06 01:52:50

【codevs2495】 水叮当的舞步的相关文章

codevs2495 水叮当的舞步

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

codevs2495 水叮当的舞步 IDA*

我打暴力不对,于是就看看题解,,,,,,IDA*就是限制搜索深度而已,这句话给那些会A*但不知道IDA*是什么玩意的小朋友 看题解请点击这里 上方题解没看懂的看看这:把左上角的一团相同颜色的范围,那个范围周围的一圈,和剩余范围分别用c[i][j]赋值为1,2,0.然后做IDA*,限制搜索深度,估值函数h为c[i][j]不为1的范围中的不同颜色数目,意思是至少要多少次才能达到要求.ans不断迭代,如果g+h>ans则退出,如果c数组全为1则说明找到方案.感觉IDA*比A*编程难度简单好多,不用建堆

bzoj 3041: 水叮当的舞步 迭代加深搜索 &amp;&amp; NOIP RP++

3041: 水叮当的舞步 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 72  Solved: 44[Submit][Status] Description 水叮当得到了一块五颜六色的格子形地毯作为生日礼物,更加特别的是,地毯上格子的颜色还能随着踩踏而改变.为了讨好她的偶像虹猫,水叮当决定在地毯上跳一支轻盈的舞来卖萌~~~地毯上的格子有N行N列,每个格子用一个0~5之间的数字代表它的颜色.水叮当可以随意选择一个0~5之间的颜色,然后轻轻地跳动一步

【wikioi】2495 水叮当的舞步(A*+迭代加深搜索)

这题我还是看题解啊囧.(搜索实在太弱.完全没想到A*,还有看题的时候想错了,.,- -) 好吧,估价还是那么的简单,判断颜色不同的数目即可(左上角的联通块不算在内) 然后A*还是一样的做法. 迭代加深还是一样的味道- 在这里我们用c[i][j]来表示左上角开始的联通块和联通块外面一层(因为要从外面一层拓展颜色),分别记为1和2 那么我们在搜索的时候,染色只要染c[i][j]为2的颜色种类,并且更新联通块(在这里不需要传图,因为一层一层的拓展下去的话,是单调递增的,所以用不到之前的颜色)我们在搜索

BZOJ 3041 水叮当的舞步

3041: 水叮当的舞步 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 120  Solved: 67[Submit][Status][Discuss] Description 水叮当得到了一块五颜六色的格子形地毯作为生日礼物,更加特别的是,地毯上格子的颜色还能随着踩踏而改变.为了讨好她的偶像虹猫,水叮当决定在地毯上跳一支轻盈的舞来卖萌~~~地毯上的格子有N行N列,每个格子用一个0~5之间的数字代表它的颜色.水叮当可以随意选择一个0~5之间的颜色

【codevs2495】水叮当的舞步

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

水叮当的舞步 深搜

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

codevs 2495 水叮当的舞步

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

水叮当的舞步

[题目描述] 地毯上的格子有N行N列,每个格子用一个0~5之间的数字代表它的颜色.水叮当可以随意选择一个0~5之间的颜色,然后轻轻地跳动一步,左上角的格子所在的联通块里的所有格子就会变成她选择的那种颜色.这里连通定义为:两个格子有公共边,并且颜色相同.水叮当想知道最少要多少步才能把所有格子的颜色变成一样的. [输入描述] 每个测试点包含多组数据.每组数据的第一行是一个整数N,表示地摊上的格子有N行N列:接下来一个N*N的矩阵,矩阵中的每个数都在0~5之间,描述了每个格子的颜色:N=0代表输入的结

「Poetize5」水叮当的舞步

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