• 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;
    } 
    
  • 相关阅读:
    【剑指offer】面试题35:第一个只出现一次的字符
    【剑指offer】面试题34:丑数
    【剑指offer】面试题33:把数组排成最小的数
    【剑指offer】面试题32:从1到n整数中1出现的次数
    【剑指offer】面试题31:连续子数组的最大和
    【剑指offer】面试题30:最小的 k 个数
    【剑指offer】面试题29:数组中出现次数超过一半的数字
    【剑指offer】面试题28:字符串的排列
    【剑指offer】面试题27:二叉搜索树与双向链表
    【剑指offer】面试题26:复杂链表的复制
  • 原文地址:https://www.cnblogs.com/For-Miku/p/15228744.html
Copyright © 2020-2023  润新知