UVA 1343 The Rotation Game

https://vjudge.net/problem/UVA-1343

题目

给出一种井字棋盘,只含数字1、2、3,只允许六种移动,问如何移动才能使棋盘中间八格数字相等,输出步数最少的操作,如果有多个步数相同的操作,输出字典序最小的操作

题解

每一步操作都有点麻烦,先写个工具模拟所有操作

先编号,方便输入和操作

只看A操作

操作后下面的数占据了上面的位置,然后就可以写程序得到每个数的新位置

工具代码

#include<bits/stdc++.h>
using namespace std;
#define REP(i,x,y) for(register int i=(x); i<(y); i++)
int arr[7][7] = {
{0,0,1,0,2,0,0},
{0,0,3,0,4,0,0},
{5,6,7,8,9,10,11},
{0,0,12,0,13,0,0},
{14,15,16,17,18,19,20},
{0,0,21,0,22,0,0},
{0,0,23,0,24,0,0}
};
int arr2[7][7];
inline void op(int fx, int fy, int dx, int dy) {
	int ix=fx+dx,iy=fy+dy;
	while(0<=ix && ix<7 && 0<=iy && iy<7) {
		arr2[ix][iy]=arr[ix-dx][iy-dy];
		ix+=dx, iy+=dy;
	}
	arr2[fx][fy]=arr[ix-dx][iy-dy];
}
int main() {
	const int fx[] = {0,0,2,4,6,6,4,2};
	const int fy[] = {2,4,6,6,4,2,0,0};
	const int dx[] = {1,1,0,0,-1,-1,0,0};
	const int dy[] = {0,0,-1,-1,0,0,1,1};
	REP(i,0,8) {
		printf("{");
		memcpy(arr2,arr,sizeof arr);
		op(fx[i],fy[i],dx[i],dy[i]);
		REP(i,0,7) {
			REP(j,0,7) {
				if(arr2[i][j])
				printf("%d,", arr2[i][j]-1);
			}
		}
		printf("}, // %c
", 'A'+i);
	}
	return 0;
}

然后就可以用IDA*写程序代码了……(因为不想写hash= =)

AC代码

#include<bits/stdc++.h>
using namespace std;
#define REP(i,x,y) for(register int i=(x); i<(y); i++)
#define _REP(i,x,y) for(i=(x); i<(y); i++)
#define REPE(i,x,y) for(register int i=(x); i<=(y); i++)
#define _REPE(i,x,y) for(i=(x); i<=(y); i++)
#ifdef sahdsg
#define DBG(a,...) printf(a, ##__VA_ARGS__)
#else
#define DBG(a,...) (void)0
#endif

const int mv[8][24] = {
{22,1,0,3,4,5,2,7,8,9,10,6,12,13,14,11,16,17,18,19,15,21,20,23}, // A
{0,23,2,1,4,5,6,7,3,9,10,11,8,13,14,15,16,12,18,19,20,17,22,21}, // B
{0,1,2,3,5,6,7,8,9,10,4,11,12,13,14,15,16,17,18,19,20,21,22,23}, // C
{0,1,2,3,4,5,6,7,8,9,10,11,12,14,15,16,17,18,19,13,20,21,22,23}, // D
{0,3,2,8,4,5,6,7,12,9,10,11,17,13,14,15,16,21,18,19,20,23,22,1}, // E
{2,1,6,3,4,5,11,7,8,9,10,15,12,13,14,20,16,17,18,19,22,21,0,23}, // F
{0,1,2,3,4,5,6,7,8,9,10,11,12,19,13,14,15,16,17,18,20,21,22,23}, // G
{0,1,2,3,10,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20,21,22,23} // H
};
int arr[24];

int target;

const int vi[]={6,7,8,11,12,15,16,17};
int md;
char ans[4][450];
bool dfs(int *oarr, int d) {
	
	int e=0;
	REP(i,0,8) {
		if(oarr[vi[i]]!=target) e++;
	}
//	DBG("#%d %d
", d,e);
	if(e+d>md) return false;
	if(e==0) return true;
	int narr[24];
	REP(i,0,8) {
		REP(j,0,24) {
			narr[mv[i][j]]=oarr[j];
		}
		ans[target][d]='A'+i;
//		putchar(ans[d]);
		if(dfs(narr, d+1)) return true;
	}
	return false;
}
int main() {
	#ifdef sahdsg
	freopen("in.txt", "r", stdin);
	#endif
	while(~scanf("%d", arr) && arr[0]) {
		REP(i,1,24) {
			scanf("%d", &arr[i]);
		}
		for(md=0;;md++) {
			bool f = false;
			for(target=1;target<=3;target++) {
				ans[target][0]=0;
				if(dfs(arr,0)) {
					if(md==0) {
						puts("No moves needed");
						printf("%d
", target);
						break;
					}
					f=true;
				}
			}
			if(f) {
				int c=-1;
				REPE(i,1,3) {
					if(ans[i][0]!=0 && ((c==-1) || (strcmp(ans[i],ans[c])<0))) {
						c=i;
					}
				}
				if(c==-1) break;
				REP(i,0,md) {
					putchar(ans[c][i]);
				}
				putchar('
');
				printf("%d
", c);
				break;
			}
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/sahdsg/p/10450948.html