UVA 11198 Dancing Digits

  爆搜吧,状态利用康拓排列可以压缩

#define fi freopen("in.txt","r",stdin)
#include <stdio.h>   
#include <iostream>
#include <string.h>   
#include <cmath>
#include <vector>
#include <set>
#include <algorithm>   
using namespace std;

#define sfint(x) scanf("%d",&x)
#define sfint2(x,y) scanf("%d%d",&x,&y)
#define sfint3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define sfstr(c) scanf("%s",c)
#define pfint(x) printf("%d\n",x)
#define fr(i,s,n) for(i=s;i<n;++i)
#define _fr(i,n,s) for(i=n-1;i>=s;--i)
#define cl(a) memset(a,0,sizeof(a))
struct State{
	int a[8];
	int dep;
	int val;
};
int a[10];
State  q[100000];
bool vst[40320];
bool prime[20];
int f[9];
void init(){
	cl(prime);
	prime[2] =1;
	prime[3] =1,prime[5]=1,prime[7]=1;prime[11] = 1;prime[13]=1;prime[17] =1;
	f[0] =1;
	int i;
	fr(i,1,9) f[i] =f[i-1]*i; 
}
int hashed(State x){
	int ret = 0;
	int i,j;
	fr(i,0,8){
		int cnt = 0;
		fr(j,i+1,8) if (abs(x.a[j])<abs(x.a[i])) cnt++;
		ret += cnt*f[7-i];
	}
	return ret;
}

void add(State & tmp,int &r){
	tmp.val = hashed(tmp);
	if (!vst[tmp.val]){
		vst[tmp.val]=1;
		tmp.dep ++;
		q[r++] = tmp;
	}
}
void bfs(){
	int f = 0,r = 1,i,j,k,c1,c2;
	State u ;
	u.dep = 0;
	fr(i,0,8) u.a[i] = a[i];
	u.val = hashed(u);
	vst[u.val]=1;
	q[0] = u;
	while(f!=r){
		u = q[f++];
		if  (u.val == 0) {
			printf("%d\n",u.dep);
			break;
		}
		fr(i,0,7){
			fr(j,i+1,8){
				if (u.a[i]*u.a[j]<0&& prime[abs(u.a[i])+abs(u.a[j])]){
					c1 = u.a[i] ;c2 = u.a[j];
					{
						State tmp = u;
						for(k = j-1;k>=i;k--){
							tmp.a[k+1] = tmp.a[k];
						}
						tmp.a[i] = c2;
						add(tmp,r);
					}{ 
						State tmp = u;
 						for(k = j-1;k>=i+1;k--){
							tmp.a[k+1] = tmp.a[k];
						}
						tmp.a[i+1] = c2;
						add(tmp,r);
					}{
						State tmp = u;
						fr(k,i+1,j){
							tmp.a[k-1] = tmp.a[k];
						}
						tmp.a[j-1] = c1;
						add(tmp,r);
					}{
						State tmp = u;
						fr(k,i+1,j+1){
							tmp.a[k-1] = tmp.a[k];
						}
						tmp.a[j] = c1;
						add(tmp,r);
					}
				}
			}
		}
	}
	if (!vst[0])printf("-1\n");
}
int main(){
	fi;
	int i;
	int cas=0;
	init();
	while (sfint(a[0]),a[0]){
		printf("Case %d: ",++cas);
		fr(i,1,8) sfint(a[i]);
		cl(vst);
		bfs();
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值