Flood-it!
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!的更多相关文章
- SYN Flood测试
由于工作需要对公司进行SYN Flood测试,在网上查了些资料,Youtube上找到最多的方法就是hping3工具来实现, 该工具已经预装在Kali下,具体操作用一条命令即可实现. hping3 -S ...
- 浅谈iptables防SYN Flood攻击和CC攻击
------------------------本文为自己实践所总结,概念性的东西不全,这里粗劣提下而已,网上很多,本文主要说下目前较流行的syn洪水攻击和cc攻击------------------ ...
- SYN Flood应如何应对
1 什么是SYN Flood攻击 在TCP三次握手时,服务器接收客户端的SYN请求,操作系统将为该请求分配一个TCP(Transmission Control Block),服务器返回一个SYN/AC ...
- Message Flood
Message Flood Time Limit: 1500MS Memory limit: 65536K 题目描述 Well, how do you feel about mobile phone? ...
- 图像处理之泛洪填充算法(Flood Fill Algorithm)
泛洪填充算法(Flood Fill Algorithm) 泛洪填充算法又称洪水填充算法是在很多图形绘制软件中常用的填充算法,最熟悉不过就是 windows paint的油漆桶功能.算法的原理很简单,就 ...
- Cisco 防止SYN Flood 攻击原理
DoS(Denial of Service拒绝服务)和DDoS(Distributed Denial of Service分布式拒绝服务)攻击是大型网站和网络服务器的安全威胁之一.2000年2月,Ya ...
- Nginx下防御HTTP GET FLOOD(CC)攻击
Nginx下防御HTTP GET FLOOD(CC)攻击 Nginx是一款轻量级的Web服务器,由俄罗斯的程序设计师Igor Sysoev所开发,最初供俄国大型的入口网站及搜寻引Rambler使用. ...
- Codeforces gym 100685 F. Flood bfs
F. FloodTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100685/problem/F Desc ...
- 扯谈网络编程之Tcp SYN flood洪水攻击
简单介绍 TCP协议要经过三次握手才干建立连接: (from wiki) 于是出现了对于握手过程进行的攻击.攻击者发送大量的SYN包,server回应(SYN+ACK)包,可是攻击者不回应ACK包,这 ...
- TCP洪水攻击(SYN Flood)的诊断和处理
TCP洪水攻击(SYN Flood)的诊断和处理 SYN Flood介绍 前段时间网站被攻击多次,其中最猛烈的就是TCP洪水攻击,即SYN Flood. SYN Flood是当前最流行的DoS(拒 ...
随机推荐
- 高可用的池化 Thrift Client 实现(源码分享)
本文将分享一个高可用的池化 Thrift Client 及其源码实现,欢迎阅读源码(Github)并使用,同时欢迎提出宝贵的意见和建议,本人将持续完善. 本文的主要目标读者是对 Thrift 有一定了 ...
- 配置supervisor 让laraver的队列实现守护进程
1,安装: #brew install supervisor 默认会安装在/usr/local/Cellar/supervisor目录 2,在etc下面新建supervisor.conf 文件,复制下 ...
- Redmine管理项目1-自定义属性
先是点击页面导航条(最上面那排菜单,有主页.我的工作台.项目.管理.帮助等)上的“管理”菜单,看到下图: 看到里面的“自定义属性”菜单了吧,点击它,可以看到下面的界面: 点击那个“新建自定义属性”菜单 ...
- itoa()函数和atoi()函数
1.int/float to string/array: C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串,下面列举了各函数的方法及其说明.● itoa():将 ...
- JS的console使用
一,console输出的几种写法: console.error('错误信息') console.info('提示信息') console.warn('警告信息') console.log('普通信息' ...
- JavaScript中Array.prototype.sort()的详解
摘抄来源:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort sor ...
- 使用navicat连接远程linux的mysql中文显示乱码的问题
在navicat对应的连接上 右键->连接属性->高级 去掉使用mysql字符集 然后上面的编码选择 (65001)utf-8 接着打开连接 找到对应的数据库 右键 数据库属性 把编码 ...
- Tomcat禁止外网访问
Tomcat中某个应用禁止外网访问 Tomcat中有多个应用,由于权限需要,将某一个主机禁止外网访问.在config/server.xml中设置: <Host name="172.16 ...
- OBIEE 缓存机制
1,EM下开关缓存和rpd中高速缓存是一件事,就是nqserver的缓存, 由nqsconfig.ini中配置决定cache是否开启. 当然rpd里面还需要设置,具体的表是否要缓存. 这部分可以看这篇 ...
- 安卓系统浏览器中select下拉按钮无法弹出选择面板奇怪问题解决
今天遇到个让人崩溃的问题: 平台: 安卓 4.0 描述: 使用 appcan 开发 hybrid 应用,手机上点击下拉选框按钮无法弹出选择面板. 说明: 发现 webkit 内核 position:f ...