再簡單說明一下題意,規定一開始按鈕狀態爲0 0 0 0 0 0,輸入終點狀態,求最少的操作步數,對於每個按鈕,有以下規定:
按鈕①:可以任意想順時針或者逆時針旋轉,一次轉動一格
按鈕②:當6個旋鈕的數字中奇數偶數個數爲相同時才能轉動,向順時針或者逆時針轉動一格
按鈕③:只能向逆時針方向轉動,一次轉動7格。
按鈕④:只能向逆時針方向轉動,一次轉動(sum % 9 + 1)格,sum爲當前六個數之和
按鈕⑤:當①③⑤這三個旋鈕數字之和正好爲9的時候才能轉動,順時針或者逆時針旋轉一格
按鈕⑥:當按鈕②的數字爲0的時候才能轉動,只能向順時針轉動,一次轉動三格。
這個題一開始反應的是能否直接用DFS並判重來做。。然而明顯不可以。
後來發現其實這肯定是個BFS的題目,進而根據題目知道終點,知道起點這個特性,想到可以用A*或者雙向BFS來做,但是不知道怎麼列啓發式函數,所以就用雙向BFS來做吧。代碼很長,因爲正向和反向不完全一樣的判斷條件,比較坑。。。未提交過,可能有錯誤,歡迎指正。
代碼如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
#include <vector>
#include <cmath>
#include <iomanip>
#include <algorithm>
#include <queue>
using namespace std;
struct VIS{
int flag;
int step;
}vis[1000001];
int dis[2] = {1, -1};
struct num{
int n[6];
int step;
friend bool operator <(num a, num b)
{
return a.step < b.step;
}
};
int ans[6];
int init[6];
bool judge(num a){
for(int i = 0; i < 6; i ++)
if(a.n[i] != ans[i]);
return false;
return true;
}
int total(num a){
int i, sum;
sum = 0;
for(i = 0; i < 6; i ++)
sum = sum * 10 + a.n[i];
return sum;
}
int bfs(void){
memset(vis, 0, sizeof(vis));
queue<num> q;
queue<num> p;
num pre, lst;
int i, t, sp = 0;
long sum;
for(i = 0; i < 6; i ++)
pre.n[i] = init[i];
sum = total(pre);
vis[sum].flag = 1;
vis[sum].step = 0;
pre.step = 0;
q.push(pre);
for(i = 0; i < 6; i ++)
lst.n[i] = ans[i];
sum = total(lst);
vis[sum].flag = 2;
vis[sum].step = 0;
lst.step = 0;
p.push(lst);
while(!q.empty() && !p.empty()){
while(q.front().step == sp){
pre = q.front();
q.pop();
for(i = 0; i < 6; i ++){
if(i == 0){
for(t = 0; t < 2; t ++){
lst = pre;
lst.n[0] = pre.n[0] + dis[t];
if(lst.n[i] < 0)
lst.n[i] += 10;
else if(lst.n[i] >= 10)
lst.n[i] -= 10;
sum = total(lst);
lst.step = pre.step + 1;
if(vis[sum].flag == 1)
continue;
if(vis[sum].flag == 2)
return lst.step + vis[sum].step;
vis[sum].flag = 1;
vis[sum].step = lst.step;
q.push(lst);
}
}
else if(i == 1){
int temp = 0;
for(int j = 0; j < 6; j ++){
if(pre.n[j] % 2)
temp ++;
else
temp --;
}
if(temp != 0)
continue;
for(t = 0; t < 2; t ++){
lst = pre;
lst.n[1] = pre.n[1] + dis[t];
if(lst.n[i] < 0)
lst.n[i] += 10;
else if(lst.n[i] >= 10)
lst.n[i] -= 10;
sum = total(lst);
lst.step = pre.step + 1;
if(vis[sum].flag == 1)
continue;
if(vis[sum].flag == 2)
return lst.step + vis[sum].step;
vis[sum].flag = 1;
vis[sum].step = lst.step;
q.push(lst);
}
}
else if(i == 2){
lst = pre;
lst.n[2] = pre.n[2] + 7;
if(lst.n[i] < 0)
lst.n[i] += 10;
else if(lst.n[i] >= 10)
lst.n[i] -= 10;
sum = total(lst);
lst. step = pre.step + 1;
if(vis[sum].flag == 1)
continue;
if(vis[sum].flag == 2)
return lst.step + vis[sum].step;
vis[sum].flag = 1;
vis[sum].step = lst.step;
q.push(lst);
}
else if(i == 3){
lst = pre;
int temp = 0;
for(int j = 0; j < 6; j ++){
temp += lst.n[j];
}
temp = temp % 9 + 1;
lst.n[3] = pre.n[3] + temp;
if(lst.n[i] < 0)
lst.n[i] += 10;
else if(lst.n[i] >= 10)
lst.n[i] -= 10;
sum = total(lst);
lst. step = pre.step + 1;
if(vis[sum].flag == 1)
continue;
if(vis[sum].flag == 2)
return lst.step + vis[sum].step;
vis[sum].flag = 1;
vis[sum].step = lst.step;
q.push(lst);
}
else if(i == 4 && (pre.n[0] + pre.n[2] + pre.n[4] == 9)){
for(t = 0; t < 2; t ++){
lst = pre;
lst.n[4] = pre.n[4] + dis[t];
if(lst.n[i] < 0)
lst.n[i] += 10;
else if(lst.n[i] >= 10)
lst.n[i] -= 10;
sum = total(lst);
lst.step = pre.step + 1;
if(vis[sum].flag == 1)
continue;
if(vis[sum].flag == 2)
return lst.step + vis[sum].step;
vis[sum].flag = 1;
vis[sum].step = lst.step;
q.push(lst);
}
}
else if(i == 5 && pre.n[1] == 0){
lst = pre;
lst.n[5] = pre.n[5] - 3;
if(lst.n[i] < 0)
lst.n[i] += 10;
else if(lst.n[i] >= 10)
lst.n[i] -= 10;
sum = total(lst);
lst. step = pre.step + 1;
if(vis[sum].flag == 1)
continue;
if(vis[sum].flag == 2)
return lst.step + vis[sum].step;
vis[sum].flag = 1;
vis[sum].step = lst.step;
q.push(lst);
}
}
}
while(p.front().step == sp){
pre = p.front();
p.pop();
for(i = 0; i < 6; i ++){
if(i == 0){
for(t = 0; t < 2; t ++){
lst = pre;
lst.n[0] = pre.n[0] + dis[t];
if(lst.n[i] < 0)
lst.n[i] += 10;
else if(lst.n[i] >= 10)
lst.n[i] -= 10;
sum = total(lst);
lst.step = pre.step + 1;
if(vis[sum].flag == 2)
continue;
if(vis[sum].flag == 1)
return lst.step + vis[sum].step;
vis[sum].flag = 2;
vis[sum].step = lst.step;
p.push(lst);
}
}
else if(i == 1){
for(t = 0; t < 2; t ++){
lst = pre;
lst.n[1] = pre.n[1] + dis[t];
if(lst.n[i] < 0)
lst.n[i] += 10;
else if(lst.n[i] >= 10)
lst.n[i] -= 10;
int temp = 0;
for(int j = 0; j < 6; j ++)
if(lst.n[j] % 2)
temp ++;
else
temp --;
if(temp != 0)
continue;
sum = total(lst);
lst.step = pre.step + 1;
if(vis[sum].flag == 2)
continue;
if(vis[sum].flag == 1)
return lst.step + vis[sum].step;
vis[sum].flag = 2;
vis[sum].step = lst.step;
p.push(lst);
}
}
else if(i == 2){
lst = pre;
lst.n[2] = pre.n[2] - 7;
if(lst.n[i] < 0)
lst.n[i] += 10;
else if(lst.n[i] >= 10)
lst.n[i] -= 10;
sum = total(lst);
lst. step = pre.step + 1;
if(vis[sum].flag == 2)
continue;
if(vis[sum].flag == 1)
return lst.step + vis[sum].step;
vis[sum].flag = 2;
vis[sum].step = lst.step;
p.push(lst);
}
else if(i == 3){
for(t = 0; t < 10; t ++){
lst.n[3] = pre.n[3] - t;
if(lst.n[i] < 0)
lst.n[i] += 10;
else if(lst.n[i] >= 10)
lst.n[i] -= 10;
int temp = 0;
for(int j = 0; j < 6; j ++){
temp += lst.n[j];
}
if(temp % 9 + 1 != i)
continue;
sum = total(lst);
lst.step = pre.step + 1;
if(vis[sum].flag == 2)
continue;
if(vis[sum].flag == 1)
return lst.step + vis[sum].step;
vis[sum].flag = 2;
vis[sum].step = lst.step;
p.push(lst);
}
}
else if(i == 4){
for(t = 0; t < 2; t ++){
lst = pre;
lst.n[4] = pre.n[4] + dis[t];
if(lst.n[i] < 0)
lst.n[i] += 10;
else if(lst.n[i] >= 10)
lst.n[i] -= 10;
if(lst.n[0] + lst.n[2] + lst.n[4] != 9)
continue;
sum = total(lst);
lst.step = pre.step + 1;
if(vis[sum].flag == 2)
continue;
if(vis[sum].flag == 1)
return lst.step + vis[sum].step;
vis[sum].flag = 2;
vis[sum].step = lst.step;
p.push(lst);
}
}
else if(i == 5 && pre.n[1] == 0){
lst = pre;
lst.n[5] = pre.n[5] + 3;
if(lst.n[i] < 0)
lst.n[i] += 10;
else if(lst.n[i] >= 10)
lst.n[i] -= 10;
sum = total(lst);
lst.step = pre.step + 1;
if(vis[sum].flag == 2)
continue;
if(vis[sum].flag == 1)
return lst.step + vis[sum].step;
vis[sum].flag = 2;
vis[sum].step = lst.step;
p.push(lst);
}
}
}
++ sp;
}
return -1;
}
int T;
int main(void){
char c;
//freopen("out.txt", "r", stdin);
//freopen("in.txt", "w",stdout);
cin >> T;
while(T --){
bool flag = false;
for(int i = 0; i < 6; i ++){
cin >> ans[i];
init[i] = 0;
if(ans[i])
flag = true;
}
if(!flag)
cout << "0" << endl;
int res = bfs();
cout << res << endl;
}
return 0;
}