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(拒 ...
随机推荐
- 关于ABP聚合根类AggregateRoot的思考
AggregateRoot和Entity的区别 AggregateRoot继承于Entity,并实现了IGeneratesDomainEvents接口 public class AggregateRo ...
- 驱动05.lcd设备驱动程序
参考s3c2410fb.c总结出框架 1.代码分析 1.1 入口函数 int __devinit s3c2410fb_init(void) { return platform_driver_regis ...
- 试图解释下ERP
ERP,字面的意思就是企业资源规划.但现在基本上是企业信息系统的统称,过去叫MIS.我们就是有这个本事,不管什么高大上的事物,很快就会做的很烂. 你可以这样理解ERP. 现在来了个订单,你需要回答下面 ...
- linux ftp安装和配置
1. 启动VSFTP服务器 A:cenos下运行:yum install vsftpd B. 登录Linux主机后,运行命令:"service vsftpd start"C. ...
- springmvc中返回页面,只在iframe中跳转,而不是整个页面,解决方法。
问题描述:在我写的主页面中用到了iframe,其中在iframe中有一个button点击提交,然后在Controller中返回页面的时候,是在iframe中打开的,而不是整个页面. 最开始我想用aja ...
- 【.NET-MVC】ASP.NET MVC学习笔记1-概述
第 1 篇:理解控制器和视图 MVC概述 MVC原理就是模型.视图.控制器的框架. (其实也是种思想,为了让前端.程序.数据分开,也是想实现低耦合.高内聚) MVC请求流程是:访问控制器,控制器来 ...
- git stash让bug来的更猛烈些吧
git stash可以用来暂存当前正在进行的工作,比如想pull最新的代码,又不想加新commit, 或者有一个紧急的bug需要修复,但是这个bug又与你已经在做的工作(还没完成)有关联.这个时候有的 ...
- 自己通过centos6.5配置NFS 成功后的笔记,希望对需要的人有点点帮助吧!
环境介绍: 服务器:centos 172.16.250.170 客户端:centos 172.16.250.172 先用rpm -qa ...
- android下拉刷新控件 android-pulltorefresh
运行效果: 介绍:ListView.ViewPager.WevView.ExpandableListView.GridView.(Horizontal)ScrollView.Fragment上下左右拉 ...
- NGINX----源码阅读----(option配置脚本)
/auto/options options文件主要负责nginx启动前配置脚本对环境变量初始化. 1.默认为环境变量赋值 help=no NGX_PREFIX= NGX_SBIN_PATH= NGX_ ...