UVA - 1343
阿新 • • 發佈:2020-09-14
The Rotation Game UVA - 1343
Problem:
Solution:
IDA*經典題,難點有兩個:
- 樂觀估價函式,因為每次移動最多導致一個1/2/3進入中間的八個格子中,所以如果當前中間的1/2/3的數量加上剩餘迭代次數小與8則必然無法到達,剪枝。
- 移動的操作方式,具體見程式碼。
Code:
/********************************************************** * @Author: Kirito * @Last Modified by: Kirito * @Remark: **********************************************************/ #include <bits/stdc++.h> #define lowbit(x) (x&(-x)) #define CSE(x,y) memset(x,y,sizeof(x)) #define INF 0x3f3f3f3f #define Abs(x) (x>=0?x:(-x)) #define FAST ios::sync_with_stdio(false);cin.tie(0); #define debug(x) cout<<#x<<"------"<<x<<endl using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef pair<ll , ll> pll; const int MAXN=111111; const int mv[8][7]={ { 0, 2, 6,11,15,20,22}, { 1, 3, 8,12,17,21,23}, {10, 9, 8, 7, 6, 5, 4}, {19,18,17,16,15,14,13}, {23,21,17,12,8,3,1}, {22,20,15,11,6,2,0}, {13,14,15,16,17,18,19}, {4,5,6,7,8,9,10} }; const int ed[8]={6,7,8,11,12,15,16,17}; int mp[25]; void mov(int x){ for(int i=1;i<7;i++){ swap(mp[mv[x][i]],mp[mv[x][i-1]]); } return; } int op; bool over(int &mxnum){ int num1=0,num2=0,num3=0; for(int i=0;i<8;i++){ if(mp[ed[i]]==1) num1++; if(mp[ed[i]]==2) num2++; if(mp[ed[i]]==3) num3++; } mxnum=max(max(num1,num2),num3); if(num1==8) {op=1;return true;} if(num2==8) {op=2;return true;} if(num3==8) {op=3;return true;} return false; } char path[MAXN]; bool ok; void dfs(int p,int q){ if(ok) return; int mxnum=0; if(over(mxnum)) {ok=true;return;} if(mxnum+q-p<8) return; int mp1[25]; memcpy(mp1,mp,sizeof(mp)); for(int i=0;i<8;i++){ if(ok) return; mov(i); path[p]='A'+i; dfs(p+1,q); memcpy(mp,mp1,sizeof(mp1)); } return; } int main() { #ifndef ONLINE_JUDGE freopen("in.in","r",stdin); #endif FAST; while(cin>>mp[0]&&mp[0]){ for(int i=1;i<24;i++){ cin>>mp[i]; } ok=false;CSE(path,'\0'); int sp=0; for(;;sp++){ dfs(0,sp); if(ok){ break; } } //debug(sp); if(!sp) cout<<"No moves needed"<<endl; else{ for(int i=0;i<sp;i++) cout<<path[i]; cout<<endl; } cout<<op<<endl; } return 0; }