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(拒 ...
随机推荐
- 【Java每日一题】20170113
20170112问题解析请点击今日问题下方的"[Java每日一题]20170113"查看(问题解析在公众号首发,公众号ID:weknow619) package Jan2017; ...
- MemoryStream和FileStream
一,FileStream对象的数据来自文件,而MemoryStream对象的数据来自内存缓冲区.这两个类都继承自Stream类. 二,抽象基类System.IO.Stream代表流,它提供Read和W ...
- sequekize
关于sequelize的准备工作这里不再赘述. 一.引入sequelize模块 var Sequelize = require('sequelize'); 二.连接数据库 var sequelize ...
- js实现购买数量加减效果
写在前面:当我们需要在多个页面都有操作数量的需求时的一种解决方案 结构: js代码: <script type="text/javascript"> function ...
- 【LeetCode】25. Reverse Nodes in k-Group
Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. k ...
- C# ObjectHelper
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- [MFC美化] Skin++使用详解-使用方法及注意事项
主要分为以下几个方面: 1.Skin++使用方法 2.使用中注意事项 一. Skin++使用方法 SkinPPWTL.dll.SkinPPWTL.lib.SkinPPWTL.h ,将三个文件及相应皮肤 ...
- ibatis动态修改select出来的字段
今天自己做了一个测试 , 动态去select出来数据库的字段, 但是我传参数都是正确的 , 可就是无法出来结果, 返回对象NULL . 表示很郁闷 , 然后就google了一下 , 关键词 : iba ...
- python 访问数据库
commit() 提交rollback() 回滚 cursor用来执行命令的方法:callproc(self, procname, args):用来执行存储过程,接收的参数为存储过程名和参数列表,返回 ...
- xml动态修改 dom4j修改
xml的动态修改需要传入的参数 xml的位置(tomcat中的发布位置).修改后的xml需要保存的位置(因为动态修改,所以建议和xml未修改前的位置相同).添加的节点的信息.或者修改的节点的信息 SA ...