ZOJ Problem Set - 1505 Solitaire
Chieh
posted @ 2018年3月12日 18:48
in ZOJ
, 212 阅读
飞机票:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=505
直接进行BFS就行,需要注意的是状态转移,对四个点进行排序,然后按100,10000,1000000的系数来判断是否访问过(剪枝),因为一个点可以上下左右跳一格或两格如果一格可以则不进行两格(剪枝)//
// main.cpp // zoj1505 // // Created by cfhaiteeh on 12/03/2018. // Copyright © 2018 cfhaiteeh. All rights reserved. // #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <queue> #include <map> #include <algorithm> using namespace std; struct he{ int ai[9]; int val; int t; }; int bi[9]; int ci[9]; map<int,int> _M; int _map[9][9]; int rn[9]; int cn[9]; int toans; bool getdir(int r,int c){ if(r<1||r>8)return 0; if(c<1||c>8)return 0; if(_map[r][c]==1)return 0; return 1; } int cm[5]; int cr[]={-1,-2,1,2,0,0,0,0}; int cc[]={0,0,0,0,-1,-2,1,2}; int getcm(){ sort(cm+1,cm+1+4); return cm[1]*1000000+cm[2]*10000+cm[3]*100+cm[4];; } bool BFS(){ queue<he> Q; he ne; for(int i=1;i<=8;i++)ne.ai[i]=bi[i]; for(int k=2;k<=8;k+=2){ cm[k/2]=ne.ai[k-1]*10+ne.ai[k]; } int ct=getcm(); _M[ct]=1; ne.val=8; ne.t=ct; Q.push(ne); while(!Q.empty()){ he c=Q.front(); Q.pop(); if(c.t==toans)return 1; if(c.val==0)continue; memset(_map,0,sizeof(_map)); for(int i=1;i<=8;i+=2){ int row=c.ai[i]; int col=c.ai[i+1]; _map[row][col]=1; } for(int i=1;i<=8;i+=2){ int row=c.ai[i]; int col=c.ai[i+1]; int st=0; for(int j=0;j<8;j++){ if(getdir(row+cr[j],col+cc[j])){ rn[++st]=row+cr[j]; cn[st]=col+cc[j]; if(j%2==0) { j++; } } } for(int j=1;j<=st;j++){ he nex; for(int k=1;k<=8;k++){ nex.ai[k]=c.ai[k]; } nex.ai[i]=rn[j]; nex.ai[i+1]=cn[j]; nex.val=c.val-1; for(int k=2;k<=8;k+=2){ cm[k/2]=nex.ai[k-1]*10+nex.ai[k]; } int ct=getcm(); if(_M[ct]==1)continue; nex.t=ct; _M[ct]=1; Q.push(nex); } } } return 0; } void init(){ _M.clear(); for(int i=2;i<=8;i++)scanf("%d",&bi[i]); for(int i=1;i<=8;i++)scanf("%d",&ci[i]); for(int k=2;k<=8;k+=2){ cm[k/2]=ci[k-1]*10+ci[k]; } int ct=getcm(); toans=ct; } int ans; void play(){ ans=BFS(); } void pri(){ if(ans)printf("YES\n"); else printf("NO\n"); } int main() { // insert code here... while(scanf("%d",&bi[1])!=EOF){ init(); play(); pri(); } return 0; }