hdoj 1043 构造

 不想清楚就开始写 bug重重 中间不知停手 贴下代码以示警戒 还不如乖乖搜!

未AC版本:

#include<cstdio>
int map[5][5];
int v,h,v1,h1;
int s[10]={1,2,3,5,6,8,7,4};
int processing[10];
char move[1000];
int a;
int center[4][2]={{1,2},{2,1},{2,3},{3,2}};
int moveable[5];

void nextclock(int *i,int *j){
	if(*i==1&&*j==1) {(*j)++;return;}
	if(*i==1&&*j==2) {(*j)++;return;}
	if(*i==1&&*j==3) {(*i)++;return;}
	if(*i==2&&*j==3) {(*i)++;return;}
	if(*i==3&&*j==3) {(*j)--;return;}
	if(*i==3&&*j==2) {(*j)--;return;}
	if(*i==3&&*j==1) {(*i)--;return;}
	if(*i==2&&*j==1) {(*i)--;return;}
}

void nextclockA(int *i,int *j){
	if(*j==1&&*i==1) {(*i)++;return;}
	if(*j==1&&*i==2) {(*i)++;return;}
	if(*j==1&&*i==3) {(*j)++;return;}
	if(*j==2&&*i==3) {(*j)++;return;}
	if(*j==3&&*i==3) {(*i)--;return;}
	if(*j==3&&*i==2) {(*i)--;return;}
	if(*j==3&&*i==1) {(*j)--;return;}
	if(*j==2&&*i==1) {(*j)--;return;}
}

int rollcheck(){
	int vv,hh,i,flag;
	vv=v1;hh=h1;
	i=0;
	processing[i++]=map[vv][hh];
	while(1){
		if(vv==1&&hh==1) {hh++;processing[i++]=map[vv][hh];if(i==8) break;}
		if(vv==1&&hh==2) {hh++;processing[i++]=map[vv][hh];if(i==8) break;}
		if(vv==1&&hh==3) {vv++;processing[i++]=map[vv][hh];if(i==8) break;}
		if(vv==2&&hh==3) {vv++;processing[i++]=map[vv][hh];if(i==8) break;}
		if(vv==3&&hh==3) {hh--;processing[i++]=map[vv][hh];if(i==8) break;}
		if(vv==3&&hh==2) {hh--;processing[i++]=map[vv][hh];if(i==8) break;}
		if(vv==3&&hh==1) {vv--;processing[i++]=map[vv][hh];if(i==8) break;}
		if(vv==2&&hh==1) {vv--;processing[i++]=map[vv][hh];if(i==8) break;}
	}
	flag=0;
	for(i=0;i<8;i++) {if(processing[i]!=s[i]) break;flag++;}
	return flag;
}

void addstep(char c){
	move[a++]=c;
}
void swap(int vd,int hd){
	switch(vd){
	case 1:map[v][h]=map[v-1][h];map[v-1][h]=0;v--;addstep('u');break;
	case -1:map[v][h]=map[v+1][h];map[v+1][h]=0;v++;addstep('d');break;
	}
	switch(hd){
	case 1:map[v][h]=map[v][h-1];map[v][h-1]=0;h--;addstep('l');break;
	case -1:map[v][h]=map[v][h+1];map[v][h+1]=0;h++;addstep('r');break;
	}
}

void rollswap1(int ei,int ej){
	int i,j;
	i=v;j=h;
	while(v!=ei||h!=ej){
		nextclock(&i,&j);
		swap(v-i,h-j);
	}
}


void rollswap2(int ei,int ej){
	int i,j;
	i=v;j=h;
	while(v!=ei||h!=ej){
		nextclockA(&i,&j);
		swap(v-i,h-j);
	}
}
void findn(int *ii,int *jj,int n){
	int i,j;
	for(i=1;i<=3;i++)
		for(j=1;j<=3;j++) 
			if(map[i][j]==n){*ii=i;*jj=j;return;}
}

int abs(int a){
	return a>0?a:-a;
}

bool tilechage(){
	int i,j,n,cmap[4][4],t,c,gi,gj,flag;
	if(v<3) swap(-1,h);
	if(h<3) swap(v,-1);
	for(i=1;i<=3;i++)
		for(j=1;j<=3;j++) cmap[i][j]=map[i][j];
	c=0;
	for(n=1;n<9;n++){
		flag=0;
		for(i=1;i<=3;i++){
			for(j=1;j<=3;j++) if(cmap[i][j]==n){flag=1;break;}
			if(flag) break;
		}
		gi=1+(n-1)/3;
		gj=1+(n-1)%3;
		if(i!=gi||j!=gj) {
			c++;
			t=cmap[i][j];
			cmap[i][j]=cmap[gi][gj];
			cmap[gi][gj]=t;
		}
	}
	if(c%2) return true;
	else return false;
}


int main(){
	int i,j,flag;
	while(scanf("%c",&map[1][1])!=EOF){
		for(i=1;i<=3;i++)
			for(j=1;j<=3;j++){
				if(!(i==1&&j==1)) while((map[i][j]=getchar())==' ');
				if(map[i][j]=='x') {
					map[i][j]=0;
					v=i;
					h=j;
				}
				else map[i][j]-='0';
			}
			getchar();
			a=0;
			if(tilechage()) {
				printf("unsolvable\n");
				continue;
			}
			while(1){
				swap(v-2,h-3);
				swap(v-2,h-2);
				findn(&v1,&h1,1);
				flag=rollcheck();
				if(flag==8) break;
				int movei,min=100,ii,jj;
				for(i=0;i<4;i++){
					moveable[i]=map[center[i][0]][center[i][1]];
					for(j=0;j<8;j++) if(s[j]==moveable[i]) {moveable[i]=j;break;}
					moveable[i]=j-flag;
					findn(&ii,&jj,processing[flag-1]);
					nextclock(&ii,&jj);
					if(moveable[i]<min&&moveable[i]>=0&¢er[i][0]!=ii&¢er[j][0]!=jj) {min=moveable[i];movei=i;}
				}
				findn(&ii,&jj,processing[flag-1]);
				swap(v-center[movei][0],h-center[movei][1]);
				if(abs(ii-jj)==1) rollswap1(ii,jj);
				else {
					nextclock(&ii,&jj);
					rollswap2(ii,jj);
				}
				if(flag==6) if(flag==rollcheck()){
					nextclock(&ii,&jj);
					nextclock(&ii,&jj);
					rollswap2(ii,jj);
				}
			}
			int r=0;
			findn(&v1,&h1,1);
			do {nextclock(&v1,&h1);r++;}
			while(abs(v1-h1)!=1);
			swap(v-v1,h-h1);
			v1=v;h1=h;
			while(map[1][1]!=1){
				nextclock(&v1,&h1);
				swap(v-v1,h-h1);}
			for(i=1;i<r;i++){
				nextclock(&v1,&h1);
				swap(v-v1,h-h1);}
			swap(v-2,h-2);
			swap(v-2,h-3);
			swap(v-3,h-3);
			move[a]='\0';
			printf("%s\n",move);
	}
	return 0;
}

当当当当!折腾了一上午,0ms版本

#include<cstdio>

int clock[4][4][2]={
		{{0,0},{0,0},{0,0},{0,0}},
		{{0,0},{1,2},{1,3},{2,3}},
		{{0,0},{1,1},{0,0},{3,3}},
		{{0,0},{2,1},{3,1},{3,2}}};
int clockA[4][4][2]={
		{{0,0},{0,0},{0,0},{0,0}},
		{{0,0},{2,1},{1,1},{1,2}},
		{{0,0},{3,1},{0,0},{1,3}},
		{{0,0},{3,2},{3,3},{2,3}}};
bool coc[4][4]={
	{0,0,0,0},
	{0,0,1,0},
	{0,1,0,1},
	{0,0,1,0}};//corner or center
int map[4][4];
int v,h;
int s[8]={1,2,3,5,6,8,7,4};
char move[1000];  
int a;
int flag;
void nextclock(int *i,int *j){  
	int ii,jj;
	ii=clock[*i][*j][0];
	jj=clock[*i][*j][1];
	*i=ii;
	*j=jj;
}  

void nextclockA(int *i,int *j){  
	int ii,jj;
	ii=clockA[*i][*j][0];
	jj=clockA[*i][*j][1];
	*i=ii;
	*j=jj;
}  

void addstep(char c){  
    move[a++]=c;  
}  


void swap(int vd,int hd){//swap(v-i,h-j) can move x to i,j while i,j and v,h have one shared edge
    switch(vd){  
	case 1:map[v][h]=map[v-1][h];map[v-1][h]=0;v--;addstep('u');break;  
	case -1:map[v][h]=map[v+1][h];map[v+1][h]=0;v++;addstep('d');break;  
	}  
	switch(hd){  
	case 1:map[v][h]=map[v][h-1];map[v][h-1]=0;h--;addstep('l');break;  
	case -1:map[v][h]=map[v][h+1];map[v][h+1]=0;h++;addstep('r');break;  
    }  
}  

void findn(int *ii,int *jj,int n){  
    int i,j;  
   for(i=1;i<=3;i++)  
        for(j=1;j<=3;j++)   
           if(map[i][j]==n){*ii=i;*jj=j;return;}  
}  

int getindex(int n){
	int i;
	for(i=0;i<8;i++) if(s[i]==n) break;
	return i;
}

void rollswap1(int ei,int ej){
	if(v==ei&&h==ej) return;
    int i,j;  
    i=v;j=h;  
    while(v!=ei||h!=ej){  
        nextclock(&i,&j);  
        swap(v-i,h-j);  
   }  
}  

void rollswap2(int ei,int ej){ 
	if(v==ei&&h==ej) return;
    int i,j;  
		i=v;j=h;      
		while(v!=ei||h!=ej){  
       nextclockA(&i,&j);  
      swap(v-i,h-j);  
    }  
}  


void insert(int n){
	int i,j;
	findn(&i,&j,n);
	if(coc[i][j]) {
		rollswap1(i,j);
		swap(v-2,h-2);
	}else{
		nextclock(&i,&j);
		rollswap2(i,j);
		swap(v-2,h-2);
	}
}
void rotate(){
	int v1,h1,i;
	findn(&v1,&h1,1);
	if(coc[v1][h1]) {printf("unsolvable\n");return;}
	nextclock(&v1,&h1);
	swap(v-v1,h-h1);
	v1=v;h1=h;
	while(map[1][1]!=1){
		nextclock(&v1,&h1);
		swap(v-v1,h-h1);}
	swap(v-2,h-2);
	swap(v-2,h-3);
	swap(v-3,h-3);
	move[a]='\0';
	printf("%s\n",move);
}
void print(){
	int i,j;

							for(i=1;i<=3;i++) {
				for(j=1;j<=3;j++) printf("%d ",map[i][j]);
				printf("\n");}
								printf("\n");
}

int main(){
	int i,j,tar,vt,ht,vtA,htA,vtC,htC,vtAA,htAA;
	char w;
	while(scanf("%c",&map[1][1])!=EOF){  
        for(i=1;i<=3;i++)  
            for(j=1;j<=3;j++){  
                if(!(i==1&&j==1)) while((map[i][j]=getchar())==' ');  
                if(map[i][j]=='x') {  
                    map[i][j]=0;  
                    v=i;  
                    h=j;  
                }  
                else map[i][j]-='0';  
            }
			getchar();
			a=0;
			if(v!=2) swap(v-2,0);
			if(h!=2) swap(0,h-2);
			for(tar=1;tar<7;tar++){
				findn(&vt,&ht,s[tar]);
				vtA=vtC=vt;
				htA=htC=ht;
				nextclockA(&vtA,&htA);
				nextclock(&vtC,&htC);
				if(map[vtA][htA]==s[tar-1]) continue;
				if(coc[vt][ht]){
					swap(v-vt,h-ht);
					insert(s[tar-1]);
				}else{
					vtAA=vtA;
					htAA=htA;
					nextclockA(&vtAA,&htAA);
					if(getindex(map[vtAA][htAA])>tar){
						swap(v-vtA,h-htA);
						swap(v-vtAA,h-htAA);
						rollswap2(vtA,htA);
						swap(v-2,h-2);
						tar--;
					}else{
						if(getindex(map[vtC][htC])>tar){
							swap(v-vtA,h-htA);
							swap(v-vt,h-ht);
							swap(v-vtC,h-htC);
							swap(v-2,h-2);
							tar--;
						}else{
							swap(v-vtA,h-htA);
							swap(v-vt,h-ht);
							rollswap1(vtA,htA);
							swap(v-2,h-2);}
					}
				}
			}
			rotate();
	}
	return 0;
}


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值