再简单说明一下题意,规定一开始按钮状态为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;
}