2 1234 2144 1111 9999
2 4
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1195
题意就是开锁,四个数字的锁,1~9没有0哟。
每次可以对任意一个数字+1或者-1,当数字为1,减1,则数字变为9。
同样,当数字为9,若+1,数字则变为1。
每次操作除了对任意一位数字+1或者-1之外,还可以对相邻位置的数字进行交换。
第一位置与第二位置 or 第二位置和第三位置 or 第三位置和第四位置
但是第一位置和第四位置不可以交换。
暴力广搜,尝试过剪枝,但发现减了就WA。。。o(╯□╰)o。。。
暴力也才62MS,等一会做个双广的来试试。
双向BFS已A,详情请戳:http://blog.csdn.net/lttree/article/details/24669525
/************************************** *************************************** * Author:Tree * *From :http://blog.csdn.net/lttree * * Title : Scrambled Polygon * *Source: hdu 1195 * * Hint : 暴力BFS * *************************************** **************************************/ #include <iostream> #include <string.h> #include <queue> using namespace std; struct Key { int k[4],step; }; bool vis[10001]; // 9^4 int ini[4],ans[4],dis[2]={-1,1}; int solu[9]={9,1,2,3,4,5,6,7,8}; bool judge(Key a) { for(int i=0;i<4;++i) if( a.k[i]!=ans[i] ) return false; return true; } // 用来做VIS数组 int total(Key a) { int i,sum; sum=0; for(i=0;i<4;++i) sum=sum*10+a.k[i]; return sum; } int bfs(void) { memset(vis,0,sizeof(vis)); queue <Key> q; Key pre,lst; int i,t,sum; for(i=0;i<4;++i) pre.k[i]=ini[i]; sum=total(pre); vis[sum]=1; pre.step=0; q.push(pre); while( !q.empty() ) { pre=q.front(); q.pop(); if( judge(pre) ) return pre.step; // 每位数 加1或减1(若相应位置与答案不同) for(i=0;i<4;++i) { if( pre.k[i]!=ans[i] ) { for(t=0; t<2; ++t) { lst=pre; lst.k[i]=solu[(pre.k[i]+dis[t])%9]; sum=total(lst); if( vis[sum] ) continue; lst.step=pre.step+1; vis[sum]=1; q.push(lst); } } } // 相邻交换 for(i=0;i<3;++i) { lst=pre; lst.k[i]=pre.k[i+1]; lst.k[i+1]=pre.k[i]; sum=total(lst); if( !vis[sum] ) { lst.step=pre.step+1; vis[sum]=1; q.push(lst); } } } } int main() { int i,s,test; char c; cin>>test; while( test-- ) { // 输入数据 for(i=0;i<4;++i) { cin>>c; ini[i]=c-'0'; } for(i=0;i<4;++i) { cin>>c; ans[i]=c-'0'; } s=bfs(); cout<<s<<endl; } return 0; }