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\n", '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\n", 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\n", 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('\n');
				printf("%d\n", c);
				break;
			}
		}
	}
	return 0;
}

 

转载于:https://www.cnblogs.com/sahdsg/p/10450948.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值