题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4127

题目意思:

给n*n的方格,每个格子有一种颜色(0~5),每次可以选择一种颜色,使得和左上角相连(颜色相同以及相邻,间接也行)的所有的格子都为该颜色。求最少的步数,使得所有的方格颜色都相同。

解题思路:

bfs+bfs死活不给过。

正确解法应该是ID(dfs+bfs).因为总共的解的步数不多。

减枝:

1、当剩余的颜色种数(至少还要这么多步)+已走的步数>设定深度时 跳出。

2、注意每次搜的时候保证比前面的方格数多。

PS:时间卡的紧,不用STL,用手写队列。

代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std; #define Maxn 10
int sa[Maxn][Maxn],n,ans,dep;
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
bool flag; struct Po
{
int x,y;
}q[80]; struct Inf
{
int cnt;
Po pp[70];
}; //存储一个连通块内的所有节点
bool vis[Maxn][Maxn];
bool iscan(int x,int y) //判断是否越界
{
if(x<=0||x>n||y<=0||y>n)
return false;
return true;
}
void bfs(Inf & s,int co[])
{
memset(vis,false,sizeof(vis));
//queue<Inf>myq;
s.cnt=0;
Po tmp;
tmp.x=1,tmp.y=1;
s.pp[++s.cnt]=tmp;
vis[1][1]=true;
//myq.push(s);
int head=0,tail=-1;
q[++tail]=tmp; while(head<=tail)
{
//Inf cur=myq.front();
//myq.pop();
Po cur=q[head];
++head; int xx=cur.x,yy=cur.y;
for(int i=0;i<4;i++)
{
int x=xx+dir[i][0],y=yy+dir[i][1];
if(!iscan(x,y)||vis[x][y]||sa[x][y]!=sa[xx][yy])
continue;
vis[x][y]=true;
Po tt;
tt.x=x,tt.y=y;
s.pp[++s.cnt]=tt;
//myq.push(s);
q[++tail]=tt;
}
}
for(int i=1;i<=n;i++) //统计还没有进入连通块内的颜色种数
for(int j=1;j<=n;j++)
{
if(!vis[i][j])
co[sa[i][j]]++;
} }
void dfs(int co,int step,int num) //当前颜色,已走步数,已联通的方格个数
{
if(step>dep||flag)
return ;
int cc[6]={0};
Inf tmp;
bfs(tmp,cc);
if(tmp.cnt<=num)//往多的方格搜,不然浪费步数
return ;
num=tmp.cnt;
//printf(":%d\n",num);
//system("pause");
if(num==n*n) //找到了
{
flag=true;
ans=step;
return ;
}
int nn=0;
for(int i=0;i<6;i++)
if(cc[i])
nn++;
if(nn+step>dep) //至少要这么多步
return ;
for(int i=0;i<6;i++)
{
if(i==co)
continue;
for(int j=1;j<=tmp.cnt;j++)
sa[tmp.pp[j].x][tmp.pp[j].y]=i;
dfs(i,step+1,num);
for(int j=1;j<=tmp.cnt;j++) //回溯
sa[tmp.pp[j].x][tmp.pp[j].y]=co;
} }
void IDA()
{
flag=false;
dep=1;
while(!flag) //迭代加深搜索
{
dfs(sa[1][1],0,0);
++dep;
}
} int main()
{
while(scanf("%d",&n)&&n)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&sa[i][j]);
IDA();
printf("%d\n",ans);
}
return 0;
}

ID(dfs+bfs)-hdu-4127-Flood-it!的更多相关文章

  1. POJ 3083 -- Children of the Candy Corn(DFS+BFS)TLE

    POJ 3083 -- Children of the Candy Corn(DFS+BFS) 题意: 给定一个迷宫,S是起点,E是终点,#是墙不可走,.可以走 1)先输出左转优先时,从S到E的步数 ...

  2. Leetcode题目104.二叉树的最大深度(DFS+BFS简单)

    题目描述: 给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例: 给定二叉树 [3,9,20,null,null, ...

  3. [LeetCode]695. 岛屿的最大面积(DFS/BFS)、200. 岛屿数量(DFS/BFS待做/并差集待做)

    695. 岛屿的最大面积 题目 给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合.你可以假设二维矩阵的四个边缘都被 ...

  4. HDU 3313 Key Vertex(dfs + bfs)

    HDU 3313 Key Vertex 题目链接 题意:一个有向无环图.求s,t之间的割点 思路:先spfa找一条最短路出来,假设不存在.就n个都是割点. 然后每次从s进行dfs,找到能经过最短路上的 ...

  5. 第三次组队赛 (DFS&BFS)

    网站:CSUST 8月1日 先总结下,不得不说死的很惨,又是第三就不说了,一共7道题,AC了5道,但是有一个组三个人是做的个人赛,有两人AK了.......Orz,然后深搜还是大问题,宽搜倒是不急了. ...

  6. poj 3083 Children of the Candy Corn(DFS+BFS)

    做了1天,总是各种错误,很无语 最后还是参考大神的方法 题目:http://poj.org/problem?id=3083 题意:从s到e找分别按照左侧优先和右侧优先的最短路径,和实际的最短路径 DF ...

  7. 最少步数(dfs + bfs +bfs优化)

    最少步数 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 这有一个迷宫,有0~8行和0~8列: 1,1,1,1,1,1,1,1,1 1,0,0,1,0,0,1,0,1 ...

  8. POJ 1426 Find The Multiple (DFS / BFS)

    题目链接:id=1426">Find The Multiple 解析:直接从前往后搜.设当前数为k用long long保存,则下一个数不是k*10就是k*10+1 AC代码: /* D ...

  9. Leetcode之深度+广度优先搜索(DFS+BFS)专题-934. 最短的桥(Shortest Bridge)

    Leetcode之广度优先搜索(BFS)专题-934. 最短的桥(Shortest Bridge) BFS入门详解:Leetcode之广度优先搜索(BFS)专题-429. N叉树的层序遍历(N-ary ...

随机推荐

  1. Android学习总结——实时显示系统时间

    我们都知道System.currentTimeMillis()可以获取系统当前的时间,这里要实时显示就可以开启一个线程,然后通过handler发消息,来实时的更新TextView上显示的系统时间.具体 ...

  2. PPT去掉图片白色背景

    双击图片,点击菜单栏“删除背景”,用矩形框选中想要的区域,然后将鼠标焦点移到图片外,单击鼠标即可.

  3. 用window.print()打印指定div里面的内容

    用window.print()打印指定div里面的内容 今天客户让添加个打印证照功能,直接用window.print()打印的是整个页面,而用以下方法就可以只打印证明了 <!--window.p ...

  4. 利用Python进行数据分析——数据规整化:清理、转换、合并、重塑(七)(1)

    数据分析和建模方面的大量编程工作都是用在数据准备上的:载入.清理.转换以及重塑.有时候,存放在文件或数据库中的数据并不能满足你的数据处理应用的要求.很多人都选择使用通用编程语言(如Python.Per ...

  5. [HeadFirst-HTMLCSS学习笔记][第八章扩大你的词汇量]

    字体 font-family,可指定多个候选 body{ font-family:Verdana,Geneva,Arial,sans-serif; } font-size 字体大小 body{ fon ...

  6. Linq:切勿使用 Count() > 0 来判断集合非空

    原文(http://www.cnblogs.com/ldp615/archive/2011/12/11/2284154.html) Linq 出现之前,我们通常使用下面的方式来判断集合是否非空,即集合 ...

  7. java基础知识1

    58.线程的基本概念.线程的基本状态以及状态之间的关系线程指在程序执行过程中,能够执行程序代码的一个执行单位,每个程序至少都有一个线程,也就是程序本身.Java中的线程有四种状态分别是:运行.就绪.挂 ...

  8. (原)使用mkl计算特征值和特征向量

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5585271.html 参考文档:mkl官方文档 lapack_int LAPACKE_sgeev(in ...

  9. 为什么在CSS中不要再使用@import

    http://www.stevesouders.com/blog/2009/04/09/dont-use-import/为什么在CSS中不要再使用@import

  10. windows下cmd导入与导出mysql 数据库

    一.导出数据库 假设导到C:\ordersys.sql 1.CMD下:输入mysqldump -u 用户名 -p 导出的数据库名>c:\ordersys.sql 2.CMD会提示输入密码:输入密 ...