Flood-it!

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4127/http://acm.split.hdu.edu.cn/showproblem.php?pid=4127

IDA*

这题题意有点不清,我去找了这个游戏玩了会才明白什么回事= =

(游戏链接:http://unixpapa.com/floodit/?sz=26&nc=6

刚开始我将状态压缩成2^64(用unsigned long long存储,当n=8全部都是一种颜色时用(unsigned long long)(-1)特判),用map去重,dfs判断每次互通的格子,A*是该状态下的颜色种类-1,一次次迭代加深,结果是TLE...

代码如下:

 #include<cstdio>
#include<cmath>
#include<iostream>
#include<set>
#include<map>
#include<cstring>
#define N 8
using namespace std;
typedef unsigned long long LL;
int mp[N][N],n,deep;
bool vis[N][N],ok;
map<LL,bool>state;
int dx[]={-,,,};
int dy[]={,,-,};
LL dfs(int px,int py,int color,LL s){
LL sta=s;
vis[px][py]=;
for(int i=;i<;++i){
int x=px+dx[i];
int y=py+dy[i];
if(<=x&&x<n&&<=y&&y<n)
if(color==mp[x][y]||(sta&((LL)<<(x*n+y)))>)
if(!vis[x][y]){
sta|=((LL)<<(x*n+y));
sta|=dfs(x,y,color,sta);
}
}
return sta;
}
LL init(){
ok=;
state.clear();
memset(vis,,sizeof(vis));
return dfs(,,mp[][],);
}
int Astar(int color,LL s){
set<int>st;
st.insert(color);
for(int i=;i<n;++i)
for(int j=;j<n;++j)
if((s&(<<(i*n+j)))==)
if(st.count(mp[i][j])==)
st.insert(mp[i][j]);
return (st.size()-);
}
void IDAstar(int color,LL sta,int step){
if(ok)return;
if(n<){
if(sta==((LL)<<n*n)-){
ok=;
return;
}
}else{
if(sta==(LL)-){
ok=;
return;
}
}
int h=Astar(color,sta);
if(step+h>deep)return;
for(int i=;i<;++i){
memset(vis,,sizeof(vis));
LL s=dfs(,,i,sta);
if(!state[s]){
state[s]=;
IDAstar(i,s,step+);
state[s]=;
}
if(ok)return;
}
}
int main(void){
while(scanf("%d",&n)){
if(n==)break;
for(int i=;i<n;++i)
for(int j=;j<n;++j)
scanf("%d",&mp[i][j]);
LL s=init();
if(n<){
if(s==((LL)<<(n*n))-){
printf("0\n");
continue;
}
}else{
if(s==(LL)-){
printf("0\n");
continue;
}
}
for(deep=;!ok;deep++){
state.clear();
state[s]=;
IDAstar(mp[][],s,);
}
printf("%d\n",deep-);
}
}

请教了下艾神,他说不要去重,太慢Orz

好好想了下,好像确实有好多优化点:状态压缩,map去重,A*函数,每次都是dfs= =

之后改进后直接用state[N][N]存储当前状态(1表示与mp[0][0]点相通的格点,2表示与mp[0][0]相通格点邻接的不同格点,0表示剩余格点),用memery[N][N]存储上一个状态;每次染色时判断有没有新增格点(state[i][j]==2&&mp[i][j]==color)有的话才染色;每次dfs的只是这次需要染色的格点域。如此复杂度大大降低了!但是还是TLE了好几发,仔细检查才发现是估价函数A*写搓了QAQ

代码如下:

 #include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<set>
#define N 8
#define M 6
#define met(x) memset(x,0,sizeof(x))
using namespace std;
int mp[N][N],n;
int state[N][N];
bool mark[M];
int dx[]={,,,-};
int dy[]={,,-,};
void dfs(int px,int py,int color){
state[px][py]=;
for(int i=;i<;++i){
int x=px+dx[i];
int y=py+dy[i];
if(<=x&&x<n&&<=y&&y<n)
if(state[x][y]!=){
if(mp[x][y]==color)dfs(x,y,color);
else state[x][y]=;
}
}
}
void init(){
met(state);
dfs(,,mp[][]);
}
int Astar(int color){
int sum=;
met(mark);
/**mark[color]=1; color不应该被mark,估价函数要写的好,搓一点都会TLE**/
for(int i=;i<n;++i)
for(int j=;j<n;++j)
if(state[i][j]!=&&!mark[mp[i][j]]){
mark[mp[i][j]]=;
sum++;
}
return sum;
}
int cnt(int color){
int sum=;
for(int i=;i<n;++i)
for(int j=;j<n;++j)
if(state[i][j]==&&mp[i][j]==color){
sum++;
dfs(i,j,color);
}
return sum;
}
bool IDAstar(int deep,int color){
if(deep<Astar(color))return ;
if(deep==)return ;
for(int i=;i<M;++i){
int memery[N][N];
memcpy(memery,state,sizeof(state));
if(cnt(i)==)continue;
if(IDAstar(deep-,i))return ;
memcpy(state,memery,sizeof(memery));
}
return ;
}
void debug(int i){
printf("\n-----debug %i -----\n",i);
}
int main(void){
while(scanf("%d",&n)){
if(n==)break;
for(int i=;i<n;++i)
for(int j=;j<n;++j)
scanf("%d",&mp[i][j]);
init();
int deep=Astar(mp[][]);
if(deep==){
printf("0\n");
}else{
while(!IDAstar(deep,mp[][]))deep++;
printf("%d\n",deep);
}
}
}

Flood-it!的更多相关文章

  1. SYN Flood测试

    由于工作需要对公司进行SYN Flood测试,在网上查了些资料,Youtube上找到最多的方法就是hping3工具来实现, 该工具已经预装在Kali下,具体操作用一条命令即可实现. hping3 -S ...

  2. 浅谈iptables防SYN Flood攻击和CC攻击

    ------------------------本文为自己实践所总结,概念性的东西不全,这里粗劣提下而已,网上很多,本文主要说下目前较流行的syn洪水攻击和cc攻击------------------ ...

  3. SYN Flood应如何应对

    1 什么是SYN Flood攻击 在TCP三次握手时,服务器接收客户端的SYN请求,操作系统将为该请求分配一个TCP(Transmission Control Block),服务器返回一个SYN/AC ...

  4. Message Flood

    Message Flood Time Limit: 1500MS Memory limit: 65536K 题目描述 Well, how do you feel about mobile phone? ...

  5. 图像处理之泛洪填充算法(Flood Fill Algorithm)

    泛洪填充算法(Flood Fill Algorithm) 泛洪填充算法又称洪水填充算法是在很多图形绘制软件中常用的填充算法,最熟悉不过就是 windows paint的油漆桶功能.算法的原理很简单,就 ...

  6. Cisco 防止SYN Flood 攻击原理

    DoS(Denial of Service拒绝服务)和DDoS(Distributed Denial of Service分布式拒绝服务)攻击是大型网站和网络服务器的安全威胁之一.2000年2月,Ya ...

  7. Nginx下防御HTTP GET FLOOD(CC)攻击

    Nginx下防御HTTP GET FLOOD(CC)攻击 Nginx是一款轻量级的Web服务器,由俄罗斯的程序设计师Igor Sysoev所开发,最初供俄国大型的入口网站及搜寻引Rambler使用. ...

  8. Codeforces gym 100685 F. Flood bfs

    F. FloodTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100685/problem/F Desc ...

  9. 扯谈网络编程之Tcp SYN flood洪水攻击

    简单介绍 TCP协议要经过三次握手才干建立连接: (from wiki) 于是出现了对于握手过程进行的攻击.攻击者发送大量的SYN包,server回应(SYN+ACK)包,可是攻击者不回应ACK包,这 ...

  10. TCP洪水攻击(SYN Flood)的诊断和处理

    TCP洪水攻击(SYN Flood)的诊断和处理   SYN Flood介绍 前段时间网站被攻击多次,其中最猛烈的就是TCP洪水攻击,即SYN Flood. SYN Flood是当前最流行的DoS(拒 ...

随机推荐

  1. SQL如何获取时间的方法?

    getdate():当前系统日期与时间 DATEADD(DAY,5,GETDATE()):当前日期的基础上加上x天 DATEDIFF(DAY,'2017-01-02','2017-01-13'):返回 ...

  2. 伪 alter 弹窗 +弹窗统一

    你应该有遇到这种情况:alert() 在手机上面显示的时候 反正是不好看  有的时候就只看到一个白色的框  看不到提示信息  反正很反人类  这时候我觉得 马上会有产品跟你说 这个要改掉. 然后我就遇 ...

  3. 关于 CentOS 自启动(服务、脚本)

    /etc/init.d /etc/rc.local 其实是软连接,所以,实际上看 /etc/rc.d/ 这个文件夹就好了 rc.local 是自启动脚本 正常情况下,用户自定义的服务在 init.d ...

  4. OpenVPN客户端证书合并到配置文件中

    这里只讲OpenVPN客户端证书合并到配置文件中,避免文件太多,管理不便! 生成的客户端证书和配置文件,客户端需要的一共有5个文件:ca.crt.client.crt.client.key.ta.ke ...

  5. MySql开启远程访问(Linux)

    Linux服务器上安装了MySql数据库服务器之后,在远程访问出现了61错误.经检查后,发现需要在MySql配置文件中取消绑定IP.具体做法如下: 打开my.cnf配置文件.连接到服务器之后,在终端中 ...

  6. C#笔记(二)变量

    C#把数据类型分为两种 ● 值类型 ● 引用类型 从概念上看:其区别是值类型直接存储其值,而引用类型存储对值的引用 这两种类型存储在内存的不同地方:值类型存储在堆栈中,而引用类型存储在托管堆上 如果变 ...

  7. RubyMine 2016.1 下载 附注册激活码 破解版方法

    注册破解方法: 在要求输入注册的界面选择激活码,然后粘贴以下注册码: 43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QTczWVlKIiwibGljZW5zZWVOYW1lIj ...

  8. fpga串口通信

    ---恢复内容开始--- 1.波特率的计算公式:9600bps 是指每秒可以传输9600位 则一位需要的时间为1/9600 约等于0.000104 开发板晶振大小为50M则传输一位需要的时间为 0.0 ...

  9. hdu1116回溯N皇后问题

    题目连接 经过思考,不难发现:恰好N个皇后放在不同行不同列,那么是不是可以转换成N个皇后所在行分别确定(一人一行)的情况下对她们的所在列的枚举. 也就是列的全排列生成问题,我们用c[x]表示x行皇后的 ...

  10. Python中fileinput模块使用

    fileinput模块可以对一个或多个文件中的内容进行迭代.遍历等操作.该模块的input()函数有点类似文件 readlines()方法,区别在于前者是一个迭代对象,需要用for循环迭代,后者是一次 ...