原题链接:https://vjudge.net/problem/UVA-1343
分类:迭代剪枝
备注:IDA*算法,模拟
令人惊讶的是最朴素的IDA*(剪枝)方法居然可以这么快。
直接判断剩下的凑不齐的数目是否大于剩下可以转的次数即可。
#include<bits/stdc++.h>
using namespace std;
int row1[7], row2[7], col1[7], col2[7];
int rowh1, rowh2, colh1, colh2, pos;
char ans[1000];
void print() {
printf("\n %d %d\n", col1[colh1], col2[colh2]);
printf(" %d %d\n", col1[(colh1 + 1) % 7], col2[(colh2 + 1) % 7]);
for (int i = 0; i < 7; i++)printf("%d", row1[(rowh1 + i) % 7]);
printf("\n %d %d\n", col1[(colh1 + 3) % 7], col2[(colh2 + 3) % 7]);
for (int i = 0; i < 7; i++)printf("%d", row2[(rowh2 + i) % 7]);
printf("\n %d %d\n", col1[(colh1 + 5) % 7], col2[(colh2 + 5) % 7]);
printf(" %d %d\n\n", col1[(colh1 + 6) % 7], col2[(colh2 + 6) % 7]);
}
int getH() {
int res = 0, num[4] = { 0 };
num[row1[(rowh1 + 2) % 7]]++;
num[row1[(rowh1 + 3) % 7]]++;
num[row1[(rowh1 + 4) % 7]]++;
num[row2[(rowh2 + 2) % 7]]++;
num[row2[(rowh2 + 3) % 7]]++;
num[row2[(rowh2 + 4) % 7]]++;
num[col1[(colh1 + 3) % 7]]++;
num[col2[(colh2 + 3) % 7]]++;
for(int i = 1; i <= 3; i++)
res = max(res ,num[i]);
return res;
}
bool ida(int now,int depth) {
//printf("last=%c,pos=%d,now=%d,dep=%d,getH=%d\n", ans[pos - 1], pos, now, depth, getH());
//print();
int h = getH();
if (h + depth - now < 8)return false;
if (now == depth) {
if(h == 8) return true;
else return false;
}
int tmp1, tmp2;
ans[pos++] = 'A';
colh1 = (colh1 + 1) % 7;
tmp1 = row1[(rowh1 + 2) % 7];
tmp2 = row2[(rowh2 + 2) % 7];
row1[(rowh1 + 2) % 7] = col1[(colh1 + 2) % 7];
row2[(rowh2 + 2) % 7] = col1[(colh1 + 4) % 7];
if (ida(now + 1, depth))return true;
else {
pos--; colh1 = (colh1 + 6) % 7;
row1[(rowh1 + 2) % 7] = tmp1;
row2[(rowh2 + 2) % 7] = tmp2;
}
ans[pos++] = 'B';
colh2 = (colh2 + 1) % 7;
tmp1 = row1[(rowh1 + 4) % 7];
tmp2 = row2[(rowh2 + 4) % 7];
row1[(rowh1 + 4) % 7] = col2[(colh2 + 2) % 7];
row2[(rowh2 + 4) % 7] = col2[(colh2 + 4) % 7];
if (ida(now + 1, depth))return true;
else {
pos--; colh2 = (colh2 + 6) % 7;
row1[(rowh1 + 4) % 7] = tmp1;
row2[(rowh2 + 4) % 7] = tmp2;
}
ans[pos++] = 'C';
rowh1 = (rowh1 + 6) % 7;
tmp1 = col1[(colh1 + 2) % 7];
tmp2 = col2[(colh2 + 2) % 7];
col1[(colh1 + 2) % 7] = row1[(rowh1 + 2) % 7];
col2[(colh2 + 2) % 7] = row1[(rowh1 + 4) % 7];
if (ida(now + 1, depth))return true;
else {
pos--; rowh1 = (rowh1 + 1) % 7;
col1[(colh1 + 2) % 7] = tmp1;
col2[(colh2 + 2) % 7] = tmp2;
}
ans[pos++] = 'D';
rowh2 = (rowh2 + 6) % 7;
tmp1 = col1[(colh1 + 4) % 7];
tmp2 = col2[(colh2 + 4) % 7];
col1[(colh1 + 4) % 7] = row2[(rowh2 + 2) % 7];
col2[(colh2 + 4) % 7] = row2[(rowh2 + 4) % 7];
if (ida(now + 1, depth))return true;
else {
pos--; rowh2 = (rowh2 + 1) % 7;
col1[(colh1 + 4) % 7] = tmp1;
col2[(colh2 + 4) % 7] = tmp2;
}
ans[pos++] = 'E';
colh2 = (colh2 + 6) % 7;
tmp1 = row1[(rowh1 + 4) % 7];
tmp2 = row2[(rowh2 + 4) % 7];
row1[(rowh1 + 4) % 7] = col2[(colh2 + 2) % 7];
row2[(rowh2 + 4) % 7] = col2[(colh2 + 4) % 7];
if (ida(now + 1, depth))return true;
else {
pos--; colh2 = (colh2 + 1) % 7;
row1[(rowh1 + 4) % 7] = tmp1;
row2[(rowh2 + 4) % 7] = tmp2;
}
ans[pos++] = 'F';
colh1 = (colh1 + 6) % 7;
tmp1 = row1[(rowh1 + 2) % 7];
tmp2 = row2[(rowh2 + 2) % 7];
row1[(rowh1 + 2) % 7] = col1[(colh1 + 2) % 7];
row2[(rowh2 + 2) % 7] = col1[(colh1 + 4) % 7];
if (ida(now + 1, depth))return true;
else {
pos--; colh1 = (colh1 + 1) % 7;
row1[(rowh1 + 2) % 7] = tmp1;
row2[(rowh2 + 2) % 7] = tmp2;
}
ans[pos++] = 'G';
rowh2 = (rowh2 + 1) % 7;
tmp1 = col1[(colh1 + 4) % 7];
tmp2 = col2[(colh2 + 4) % 7];
col1[(colh1 + 4) % 7] = row2[(rowh2 + 2) % 7];
col2[(colh2 + 4) % 7] = row2[(rowh2 + 4) % 7];
if (ida(now + 1, depth))return true;
else {
pos--; rowh2 = (rowh2 + 6) % 7;
col1[(colh1 + 4) % 7] = tmp1;
col2[(colh2 + 4) % 7] = tmp2;
}
ans[pos++] = 'H';
rowh1 = (rowh1 + 1) % 7;
tmp1 = col1[(colh1 + 2) % 7];
tmp2 = col2[(colh2 + 2) % 7];
col1[(colh1 + 2) % 7] = row1[(rowh1 + 2) % 7];
col2[(colh2 + 2) % 7] = row1[(rowh1 + 4) % 7];
if (ida(now + 1, depth))return true;
else {
pos--; rowh1 = (rowh1 + 6) % 7;
col1[(colh1 + 2) % 7] = tmp1;
col2[(colh2 + 2) % 7] = tmp2;
}
return false;
}
int main(void) {
//freopen("in.txt","r",stdin);
while (~scanf("%d", &col1[0]) && col1[0]){
scanf("%d %d %d", &col2[0], &col1[1], &col2[1]);
for (int i = 0; i < 7; i++)scanf("%d", &row1[i]);
col1[2] = row1[2]; col2[2] = row1[4];
scanf("%d %d", &col1[3], &col2[3]);
for (int i = 0; i < 7; i++)scanf("%d", &row2[i]);
col1[4] = row2[2]; col2[4] = row2[4];
scanf("%d %d %d %d", &col1[5], &col2[5], &col1[6], &col2[6]);
rowh1 = rowh2 = colh1 = colh2 = pos = 0;
int dep = 0;
while (!ida(0, dep))dep++;
if (dep)for (int i = 0; i < dep; i++)printf("%c", ans[i]);
else printf("No moves needed");
printf("\n%d\n", row1[(rowh1 + 2) % 7]);
}
return 0;
}