【HDU】1693 Eat the Trees
http://acm.hdu.edu.cn/showproblem.php?pid=1693
题意:n×m的棋盘求简单回路(可以多条)覆盖整个棋盘的方案,障碍格不许摆放。(n,m<=11)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; typedef long long ll;
struct H {
static const int M=1000007;
struct E { int next, to; }e[M<<1];
int ihead, cnt, hash[M];
ll sum[M];
H() { ihead=cnt=0; memset(hash, -1, sizeof hash); memset(sum, 0, sizeof sum); }
bool find(int x, int &pos) {
pos=x%M;
while(1) { if(hash[pos]==x) return false; if(hash[pos]==-1) break; ++pos; if(pos==M) pos=0; }
hash[pos]=x; return true;
}
void ins(int a, ll b) {
int pos; if(!find(a, pos)) { sum[pos]+=b; return; }
e[++cnt].next=ihead; ihead=cnt; e[cnt].to=pos; sum[pos]=b;
}
void clr() { for(int i=ihead; i; i=e[i].next) hash[e[i].to]=-1, sum[e[i].to]=0; ihead=cnt=0; }
}T1, T2; #define BIT(a,b) ((a)<<((b)<<1))
#define CLR(a,b) (a^=((a)&BIT(3,b)))
#define GET(a,b) (3&((a)>>((b)<<1))) const int N=11;
int n, m;
ll ans;
bool mp[N][N]; int find(int s, int col, int flag) {
int sum=0;
if(flag) {
for(int i=col; i<=m; ++i) {
int k=GET(s, i);
if(k==1) ++sum;
if(k==2) --sum;
if(!sum) return i;
}
}
else {
for(int i=col; i>=0; --i) {
int k=GET(s, i);
if(k==1) --sum;
if(k==2) ++sum;
if(!sum) return i;
}
}
return -1;
}
void print(int s) {
for(int i=0; i<=m; ++i) { int k=GET(s, i); if(k==0) putchar('#'); else if(k==1) putchar('('); else if(k==2) putchar(')'); }
puts("");
}
#define F puts("error");
bool next(int s, int row, int col, bool U, bool D, bool L, bool R, int &t) {
if((row==n-1&&D) || (row==0&&U) || (col==m-1&&R) || (col==0&&L)) return 0;
if((D&&!mp[row+1][col]) || (R&&!mp[row][col+1])) return 0;
int l=GET(s, col), u=GET(s, col+1), d=0, r=0;
// printf("State:"); print(s);
// printf("row:%d, col:%d, U:%d, D:%d, L:%d, R:%d ", row, col, U, D, L, R);
// printf(" left:"); if(l==1) printf("("); if(l==2) printf(")"); if(l==0) printf("#");
// printf(" uptp:"); if(u==1) printf("("); if(u==2) printf(")"); if(u==0) printf("#"); puts("");
if((l&&!L) || (!l&&L) || (u&&!U) || (!u&&U)) return 0;
t=s; //puts("============\nfirst:"); print(t);
CLR(t, col);
CLR(t, col+1);
if(!l && !u) {
if(R && D) d=1, r=2;
}
else if(l && u) {
if(l==1 && u==1) {
int pos=find(s, col+1, 1);
CLR(t, pos);
t|=BIT(1, pos);
}
else if(l==2 && u==2) {
int pos=find(s, col, 0);
CLR(t, pos);
t|=BIT(2, pos);
}
}
else if(l && !u) {
if(D) d=l, r=0;
if(R) d=0, r=l;
}
else if(!l && u) {
if(D) d=u, r=0;
if(R) d=0, r=u;
}
t|=BIT(d, col);
t|=BIT(r, col+1);
if(col==m-1) t<<=2; //puts("=============\nnext"); print(t);
return 1;
} void bfs() {
H *q1, *q2;
q1=&T1; q2=&T2;
q1->clr();
q2->clr();
q1->ins(0, 1);
for(int row=0; row<n; ++row) for(int col=0; col<m; ++col) {
q2->clr(); //printf("q1->cnt:%d\n", q1->cnt);
for(int i=q1->ihead; i; i=q1->e[i].next) {
int s=q1->hash[q1->e[i].to], t; //print(s); //这里犯逗了啊.....我一开始竟然没写hash这个....我去...
ll sum=q1->sum[q1->e[i].to];
if(!mp[row][col]) { if(next(s, row, col, 0, 0, 0, 0, t)) q2->ins(t, sum); }
else {
if(next(s, row, col, 1, 1, 0, 0, t)) q2->ins(t, sum);
if(next(s, row, col, 1, 0, 1, 0, t)) q2->ins(t, sum);
if(next(s, row, col, 1, 0, 0, 1, t)) q2->ins(t, sum);
if(next(s, row, col, 0, 1, 1, 0, t)) q2->ins(t, sum);
if(next(s, row, col, 0, 1, 0, 1, t)) q2->ins(t, sum);
if(next(s, row, col, 0, 0, 1, 1, t)) q2->ins(t, sum);
}
}
swap(q1, q2);
}
for(int i=q1->ihead; i; i=q1->e[i].next) ans+=q1->sum[q1->e[i].to];
} int main() {
int cs, temp; scanf("%d", &cs);
for(int cc=1; cc<=cs; ++cc) {
ans=0;
scanf("%d%d", &n, &m);
for(int i=0; i<n; ++i) for(int j=0; j<m; ++j) {
scanf("%d", &temp);
mp[i][j]=temp;
}
bfs();
printf("Case %d: There are %lld ways to eat the trees.\n", cc, ans);
}
return 0;
}
犯逗了啊啊啊啊啊啊啊啊啊啊...本来一裸的插头dp...............
我竟然在调用hash的时候忘记套会实际值了啊啊啊啊啊啊啊..........
调了1h啊啊啊啊啊啊.....................
然后本题就是上一题随便改一改就行了...
【HDU】1693 Eat the Trees的更多相关文章
- 【HDU】1693:Eat the Trees【插头DP】
Eat the Trees Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- 【HDU】4888 Redraw Beautiful Drawings 网络流【推断解是否唯一】
传送门:pid=4888">[HDU]4888 Redraw Beautiful Drawings 题目分析: 比赛的时候看出是个网络流,可是没有敲出来.各种反面样例推倒自己(究其原因 ...
- hdu 1693 : Eat the Trees 【插头dp 入门】
题目链接 题意: 给出一个n*m大小的01矩阵,在其中画线连成封闭图形,其中对每一个值为1的方格,线要恰好穿入穿出共两次,对每一个值为0的方格,所画线不能经过. 参考资料: <基于连通性状态压缩 ...
- hdu 1693 Eat the Trees——插头DP
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1693 第一道插头 DP ! 直接用二进制数表示状态即可. #include<cstdio> # ...
- HDU 1693 Eat the Trees ——插头DP
[题目分析] 吃树. 直接插头DP,算是一道真正的入门题目. 0/1表示有没有插头 [代码] #include <cstdio> #include <cstring> #inc ...
- HDU 1693 Eat the Trees(插头DP、棋盘哈密顿回路数)+ URAL 1519 Formula 1(插头DP、棋盘哈密顿单回路数)
插头DP基础题的样子...输入N,M<=11,以及N*M的01矩阵,0(1)表示有(无)障碍物.输出哈密顿回路(可以多回路)方案数... 看了个ppt,画了下图...感觉还是挺有效的... 参考 ...
- HDU 1693 Eat the Trees(插头DP)
题目链接 USACO 第6章,第一题是一个插头DP,无奈啊.从头看起,看了好久的陈丹琦的论文,表示木看懂... 大体知道思路之后,还是无法实现代码.. 此题是插头DP最最简单的一个,在一个n*m的棋盘 ...
- HDU 1693 Eat the Trees
第一道(可能也是最后一道)插头dp.... 总算是领略了它的魅力... #include<iostream> #include<cstdio> #include<cstr ...
- HDU - 1693 Eat the Trees(多回路插头DP)
题目大意:要求你将全部非障碍格子都走一遍,形成回路(能够多回路),问有多少种方法 解题思路: 參考基于连通性状态压缩的动态规划问题 - 陈丹琦 下面为代码 #include<cstdio> ...
随机推荐
- Spring.Net学习之简单的知识点(一)
1.Spring.Net是一个开源的应用程序框架,可以简化开发主要功能(1)实现控制反转(IOC/DI),也就是不要直接new,依赖于接口(2)面向切面编程(AOP),就是向程序中利用委托注册事件简单 ...
- 几年前做家教写的C教程(之一)
C语言学习宝典 首先让我们认识什么是C语言. C语言是一种计算机开发语言,是一种非常基础的开发语言.能够用C语言做很多事情.C语言是顺序执行的程序. 程序应该包括数据描述,数据操作. C语言的数据类型 ...
- 【翻译十九】-java之执行器
Executors In all of the previous examples, there's a close connection between the task being done by ...
- AngularJS——依赖注入
依赖注入 依赖注入(DI)是一个经典的设计模式, 主要是用来处理组件如何获得依赖的问题.关于DI,推荐阅读Martin Flower的文章(http://martinfowler.com/art ...
- SSAS Cube 维度成员关系Rigid 和 Flexible
维度成员关系指示成员关系是否随时间而更改. 值为 Rigid 和 Flexible,前者表示成员之间的关系不随时间而更改,后者表示成员之间的关系随时间而更改. 默认值为 Flexible. 指定适 ...
- play-framework的安装与使用
一.下载: 到http://www.playframework.com/download下载 解压好包,然后输入: activator ui 访问:http://127.0.0.1:8888/home
- go sample-base64
GoSample-base64 package mainimport ( "encoding/base64" "fmt")func base64Encode(s ...
- Getting Started with Blocks
本文来源为:developer.apple.com,仅仅是博主练习排版所用. Getting Started with Blocks The following sections help you t ...
- 不通过App Store实现ios应用分发下载安装
最近公司的项目准备着手宣传工作了,宣传手册上要印制App的下载地址二维码,但是客户端应用还未上线,需要一种临时的方案解决应用分发下载问题,通常ios应用必须通过苹果应用商店才能下载安装,但是也可以看到 ...
- 类中用const限定的成员函数
本文转自http://blog.csdn.net/whyglinux/article/details/602329 类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非 ...