http://acm.fzu.edu.cn/problem.php?pid=1977

题意:n×m的网格,有3种格子,'O'必须经过、'*'可以选择经过、'X'不能经过。现在要求路径经过所有'O'且是简单回路的数量

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; typedef long long ll;
struct H {
static const int M=799997;
struct E { int next, to; }e[M];
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=15;
int n, m, all;
ll ans;
int 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), flag=GET(s, m+1), d=0, r=0;
if((l&&!L) || (!l&&L) || (u&&!U) || (!u&&U)) return 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("");
t=s;
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==1 && u==2) flag=1;
}
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);
t&=all;
if(flag) t|=BIT(1, m+1);
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, flag=GET(s, m+1); //print(s);
ll sum=q1->sum[q1->e[i].to];
if(mp[row][col]==2 && flag) continue;
if(mp[row][col]<=1) { if(next(s, row, col, 0, 0, 0, 0, t)) q2->ins(t, sum); }
if(mp[row][col]>=1 && !flag) { //忘记判flag又调了好久...
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; scanf("%d", &cs);
char s[N];
for(int cc=1; cc<=cs; ++cc) {
ans=0;
scanf("%d%d", &n, &m); all=BIT(1, m+1)-1;
for(int i=0; i<n; ++i) {
scanf("%s", s);
for(int j=0; j<m; ++j) {
if(s[j]=='*') mp[i][j]=1;
else if(s[j]=='O') mp[i][j]=2;
else mp[i][j]=0;
}
}
bfs();
printf("Case %d: %I64d\n", cc, ans);
}
return 0;
}

  


今天犯逗技能开到max?

竟然没有考虑已经有环了不需要再拓展状态的情况QAQ

本题其实就是模板题。只不过我们并不知道环在哪里被链接,因此我们再开一个状态表示当前轮廓线是否已经是环。

【FZU】1977 Pandora adventure的更多相关文章

  1. FZU 1977 Pandora adventure (DP)

    题意:给定一个图,X表示不能走,O表示必须要走,*表示可走可不走,问你多少种走的法,使得形成一个回路. 析: 代码如下: #pragma comment(linker, "/STACK:10 ...

  2. FZU 1977 Pandora adventure (插头DP,常规)

    题意:有一个n*m矩阵,其中有些格子必走,有些格子不可走,其他格子是可走也可不走,问有多少条哈密顿回路? 思路: 本来是一道很简单的题,代码写多了连白痴bug都查不出了,竟然用i>=ex& ...

  3. 【FZU】2152 文件系统

     Problem 2152 文件系统 Accept: 63    Submit: 126 Time Limit: 1000 mSec    Memory Limit : 32768 KB  Probl ...

  4. FZU1977 Pandora adventure —— 插头DP

    题目链接:https://vjudge.net/problem/FZU-1977  Problem 1977 Pandora adventure Accept: 597    Submit: 2199 ...

  5. 【计算几何】FZU Problem 2270 Two Triangles

    http://acm.fzu.edu.cn/problem.php?pid=2270 [题意] 给定6到10个点,从中选出6个不同的点组成两个三角形,使其中一个三角形可以通过另一个三角形平移和旋转得到 ...

  6. FZU 1056 扫雷游戏【搜索】

    Accept: 2584    Submit: 6790Time Limit: 1000 mSec    Memory Limit : 32768 KB Problem Description 扫雷是 ...

  7. FZU 1078 计算循环冗余码【模拟】

    计算机网络中采用循环冗余码来校验数据的正确性.其原理是:发送方计算出待发送的二进制数据的循环冗余码,并随同原数据一起发送到接收方:接收方通过重新计算接收到的数据的循环冗余码,并和收到的循环冗余码进行比 ...

  8. FZU 2124 FOJ 2124 吃豆人【BFS】

     Problem 2124 吃豆人 Accept: 134    Submit: 575 Time Limit: 1000 mSec    Memory Limit : 32768 KB  Probl ...

  9. 【NLP】Python NLTK获取文本语料和词汇资源

    Python NLTK 获取文本语料和词汇资源 作者:白宁超 2016年11月7日13:15:24 摘要:NLTK是由宾夕法尼亚大学计算机和信息科学使用python语言实现的一种自然语言工具包,其收集 ...

随机推荐

  1. 【JAVA集合框架之Set】

    一.Set概述. Set集合的特点是元素不允许重复,而且是无序的(添加和取出的顺序不一致). Set接口中的方法和Collection接口中的方法几乎相同,略. Set接口下常用的两个类:HashSe ...

  2. C#在excel中添加超链接

    1.新建一个项目 2.给项目添加引用:Microsoft Excel 12.0 Object Library (2007版本) using Excel = Microsoft.Office.Inter ...

  3. jq与js 区别

    $(this).html(666); <div id="a">123</div> <script> $("#a").clic ...

  4. php 以图搜图

    感知哈希算法count < =5 匹配最相似count > 10 两张不同的图片var_dump(ImageHash::run('1.jpg’, '2.jpg’)); <?php c ...

  5. WPF QuickStart系列之样式和模板(Style and Template)

    在WPF桌面程序中,当我们想构建一个统一的UI表现时(在不同操作系统下,显示效果一致),此时我们就需要使用到WPF中的样式和模板技术.简单来说,如果我们需要简单的给一个Button设置宽,高,Marg ...

  6. js中ascii码的转换

    今天在把原来用C写的程序移植到javascript上,但是有个地方一直调不通,后来才发现是js奇葩的字符处理出的问题.c中使用的字符处理比如加上一个字符值强制转换一下,在js中就行不通了. 但是js提 ...

  7. (译)【Unity教程】使用Unity开发Windows Phone上的横版跑酷游戏

    译者注: 目前移动设备的跨平台游戏开发引擎基本都是采用Cocos2d-x或者Unity.一般而言2d用cocos2d-x 3d用unity,但是对于Windows Phone开发者, cocos2d- ...

  8. 使用Jmeter进行http接口性能测试

    在进行网页或应用程序后台接口开发时,一般要及时测试开发的接口能否正确接收和返回数据,对于单次测试,Postman插件是个不错的Http请求模拟工具. 但是Postman只能模拟单客户端的单次请求,而对 ...

  9. 注解:【有连接表的】Hibernate单向1->N关联

    Person与Address关联:单向1->N,[有连接表的] Person.java package org.crazyit.app.domain; import java.util.Hash ...

  10. loadrunner怎么将变量保存到参数中

    用这个lr_save_string 函数 char *b = "很简单";lr_save_string(b,"b"); lr_output_message(&q ...