zoukankan      html  css  js  c++  java
  • 【POJ】1739 Tony's Tour

    http://poj.org/problem?id=1739

    题意:n×m的棋盘,'#'是障碍,'.'是空白,求左下角走到右下角且走过所有空白格子的方案数。(n,m<=8)

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    typedef long long ll;
    #define BIT(a,b) ((a)<<((b)<<1))
    #define CLR(a,b) (a^=((a)&BIT(3,b)))
    #define GET(a,b) (((a)>>((b)<<1))&3)
    int n, m, all, lastx, lasty;
    bool mp[12][12];
    
    int find(int col, int flag, int s) {
    	int sum=0;
    	if(flag==0) {
    		for(int i=col; i>=0; --i) {
    			int k=GET(s, i);
    			if(k==1) --sum;
    			if(k==2) ++sum;
    			if(!sum) return i;
    		}
    	}
    	else {
    		for(int i=col; i<=m; ++i) {
    			int k=GET(s, i);
    			if(k==1) ++sum;
    			if(k==2) --sum;
    			if(!sum) return i;
    		}
    	}
    	return -1;
    }
    bool next(int s, int row, int col, bool U, bool D, bool L, bool R, int &T) {
    	if((col==0 && L) || (col==m-1 && R)) return 0;
    	if((row==0 && U) || (row==n-1 && D)) 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;
    	if((!l && L) || (!u && U) || (l && !L) || (u && !U)) return 0;
    	T=s;
    	CLR(T, col);
    	CLR(T, col+1);
    	if(!l && !u) { if(D && R) d=1, r=2; }
    	else if(l && u) {
    		if(l==1 && u==1) {
    			int pos=find(col+1, 1, s);
    			CLR(T, pos);
    			T|=BIT(1, pos);
    		}
    		else if(l==2 && u==2) {
    			int pos=find(col, 0, s);
    			CLR(T, pos);
    			T|=BIT(2, pos);
    		}
    		else if(l==1 && u==2) { if(row!=lastx || col!=lasty) return 0; }
    	}
    	else if(l && !u) { if(D) d=l; if(R) r=l; }
    	else if(!l && u) { if(D) d=u; if(R) r=u; }
    	T|=BIT(d, col);
    	T|=BIT(r, col+1); if(col==m-1) T<<=2, T&=all; //printf("t:"); print(T); puts("");
    	return 1;
    }
    
    struct H {
    	static const int M=1000007;
    	struct E { int next, to; }e[M];
    	int head, cnt, hash[M];
    	ll sum[M];
    	H() { memset(hash, -1, sizeof hash); memset(sum, 0, sizeof sum); cnt=head=0; }
    	bool find(int x, int &pos) {
    		pos=x%M;
    		while(1) { if(hash[pos]==x) return 0; else if(hash[pos]==-1) break; ++pos; if(pos==M) pos=0; }
    		hash[pos]=x;
    		return 1;
    	}
    	void ins(int t, ll d) { int pos; if(!find(t, pos)) { sum[pos]+=d; return; } e[++cnt].next=head; head=cnt; e[cnt].to=pos; sum[pos]=d; }
    	void clr() { for(int i=head; i; i=e[i].next) hash[e[i].to]=-1, sum[e[i].to]=0; head=0; cnt=0; }
    }T1, T2;
    
    ll bfs() {
    	H *q1=&T1, *q2=&T2;
    	q1->clr(); q1->ins(0, 1);
    	for(int row=0; row<n; ++row) for(int col=0; col<m; ++col) {
    		q2->clr();
    		for(int i=q1->head; i; i=q1->e[i].next) {
    			ll sum=q1->sum[q1->e[i].to];
    			int s=q1->hash[q1->e[i].to], t;
    			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);
    	}
    	ll ans=0;
    	for(int i=q1->head; i; i=q1->e[i].next) ans+=q1->sum[q1->e[i].to];
    	return ans;
    }
    
    int main() {
    	char s[20];
    	while(scanf("%d%d", &n, &m), n|m) {
    		for(int i=2; i<n+2; ++i) {
    			scanf("%s", s+2);
    			for(int j=2; j<m+2; ++j) if(s[j]=='#') mp[i][j]=1; else mp[i][j]=0;
    		}
    		n+=2; m+=4;
    		for(int i=0; i<n; ++i) mp[i][1]=mp[i][m-2]=1;
    		for(int i=0; i<m; ++i) mp[1][i]=1;
    		for(int i=0; i<m; ++i) mp[0][i]=0;
    		for(int i=0; i<n; ++i) mp[i][0]=mp[i][m-1]=0;
    		mp[n-1][1]=mp[n-1][m-2]=0;
    		lastx=n-1; lasty=m-1;
    		all=BIT(1, m+1)-1;
    		printf("%lld
    ", bfs());
    	}
    	return 0;
    }
    

      


    模板题...

    将图用墙先封起来,然后开一条小路从左下角旋转到右下角,然后就是裸的求简单回路的问题辣...正确性很显然吧...

  • 相关阅读:
    chrome 修改请求头的小工具
    spring boot整合shiro引用配置文件配置是出现的问题
    jquery ztree 复选框
    表单input中disabled提交后得不到值的解决办法
    大文件编辑器
    记一次差点删库跑路的事故
    简单的记录一次简单的优化
    mysql 死锁解决办法
    centos6,7中防火墙基本用法
    案例3-ubuntu和centos中自动部署tomcat相关服务的脚本
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4231342.html
Copyright © 2011-2022 走看看