zoukankan      html  css  js  c++  java
  • POJ1198 Solitaire

    Lisa
    一个疯狂的双向bfs
    压缩一状态,用一个8位int,其中每2位表示一个坐标,这样最差情况下开88888888的int数组,太荒谬了,那就换成一个map,存储状态

    这四个球没有区别,所以我们保存状态按照一个固定的顺序保存就可以了

    然后就是繁琐的步骤

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<map>
    #include<queue>
    using namespace std;
    map<int,int> ma;
    queue<int> q1,q2;
    int now;
    int x;
    char c;
    int vis[9][9];
    pair<int,int> cnt[5]; 
    int mx[5]={0,0,1,-1};
    int my[5]={1,-1,0,0};
    void bfs1(){
    	int le=q1.size();
    	while(le--){
    	int now=q1.front();
    	q1.pop();
    	int tem=1;
    	int x,y;
    	for(int i=1;i<=4;++i){
    		if(i==1){
    			x=now%10;
    			y=now/10%10;
    		}else{
    			tem*=100;
    			x=now/tem%10;
    			y=now/tem/10%10;
    		}
    		vis[x][y]=1;
    		cnt[i].first=x;
    		cnt[i].second=y;
    	}
    	int tx;
    	int ty;
    	tem=1;
    	for(int i=1;i<=4;++i){ 
    		for(int j=1;j<=4;++j){
    			tx=cnt[i].first;
    			ty=cnt[i].second;
    			while(vis[tx][ty]){
    				tx+=mx[j-1];
    				ty+=my[j-1];
    			}
    			if(tx<=0||tx>8||ty<=0||ty>8){
    				continue;
    			}
    			int ns=0;
    			vis[tx][ty]=1;
    			vis[cnt[i].first][cnt[i].second]=0;
    			for(int ii=1;ii<=8;++ii){
    				for(int jj=1;jj<=8;++jj){
    					if(vis[ii][jj]){
    						ns=ns*100+jj*10+ii;
    					} 
    				}
    			}
    			vis[cnt[i].first][cnt[i].second]=1;
    			vis[tx][ty]=0;
    			if(ma[ns]==1){
    				continue;
    			}
    			if(ma[ns]==2){
    				printf("YES");
    				exit(0);
    			}
    			ma[ns]=1;
    			q1.push(ns);
    		}
    	}
    	for(int i=1;i<=4;++i){
    		vis[cnt[i].first][cnt[i].second]=0;
    	}
    	}
    }
    void bfs2(){
    	int le=q2.size();
    	while(le--){
    	int now=q2.front();
    	q2.pop();
    	int tem=1;
    	int x,y;
    	for(int i=1;i<=4;++i){
    		if(i==1){
    			x=now%10;
    			y=now/10%10;
    		}else{
    			tem*=100;
    			x=now/tem%10;
    			y=now/tem/10%10;
    		}
    		vis[x][y]=1;
    		cnt[i].first=x;
    		cnt[i].second=y;
    	}
    	int tx;
    	int ty;
    	tem=1;
    	for(int i=1;i<=4;++i){
    		for(int j=1;j<=4;++j){
    			tx=cnt[i].first;
    			ty=cnt[i].second;
    			while(vis[tx][ty]){
    				tx+=mx[j-1];
    				ty+=my[j-1];
    			}
    			if(tx<=0||tx>8||ty<=0||ty>8){
    				continue;
    			}
    			int ns=0;
    			vis[tx][ty]=1;
    			vis[cnt[i].first][cnt[i].second]=0;
    			for(int ii=1;ii<=8;++ii){
    				for(int jj=1;jj<=8;++jj){
    					if(vis[ii][jj]){
    						ns=ns*100+jj*10+ii;
    					} 
    				}
    			}
    			vis[cnt[i].first][cnt[i].second]=1;
    			vis[tx][ty]=0;
    			if(ma[ns]==2){
    				continue;
    			}
    			if(ma[ns]==1){
    				printf("YES");
    				exit(0);
    			}
    			ma[ns]=2;
    			q2.push(ns);
    		}
    	}
    	for(int i=1;i<=4;++i){
    		vis[cnt[i].first][cnt[i].second]=0;
    	}
    	}
    }
    int y;
    int main(){
    	for(int i=1;i<=4;++i){
    		cin>>x>>y;
    		vis[x][y]=1;
    	}
    	now=0;
    	int mr=1; 
    	for(int ii=1;ii<=8;++ii){
    		for(int jj=1;jj<=8;++jj){
    			if(vis[ii][jj]){
    				now=now*100+jj*10+ii;
    				vis[ii][jj]=0;
    				} 
    			}
    		}
    	q1.push(now);
    	ma[now]=1;
    	now=0;
    	for(int i=1;i<=4;++i){
    		cin>>x>>y;
    		vis[x][y]=1;
    	}
    	mr=1; 
    	for(int ii=1;ii<=8;++ii){
    		for(int jj=1;jj<=8;++jj){
    			if(vis[ii][jj]){
    				now=now*100+jj*10+ii;
    				vis[ii][jj]=0;
    				} 
    			}
    		}
    	q2.push(now);
    	ma[now]=2;
    	for(int i=1;i<=8;++i){
    		if(i&1){
    			bfs1();
    		}else{
    			bfs2();
    		}
    	}
    	cout<<"NO";
    	return 0;
    } 
    
  • 相关阅读:
    抓住六个点,谈唯品会的峰值系统应对实践
    从服务端架构设计角度,深入理解大型APP架构升级
    腾讯微信技术总监周颢:一亿用户增长背后的架构秘密
    App服务端架构变迁
    微服务、SOA 和 API对比与分析
    QPS从0到4000请求每秒,谈达达后台架构演化之路
    重构心法——打造高质量代码
    [转]使用 C++11 编写 Linux 多线程程序
    [转]编译防火墙——C++的Pimpl惯用法解析
    [转]C++ 取代switch的三种方法
  • 原文地址:https://www.cnblogs.com/For-Miku/p/15228744.html
Copyright © 2011-2022 走看看