题意:
2n个棋子排在一条长2n+1的线上 白色全在最左端黑色全在右端 每次操作可以移动一个棋子到空位或者跳一个棋子到空位(最多跳一个棋子) 问最少多少操作可以使白色全在右端黑色全在左端
思路:
最优的策略可以想出来 就是先把棋子排成黑白交错 然后不断把黑的往左白的往右移
例子里的提示也足够想到策略 最主要是代码怎么写
我的做法就是乱搞… 反正写出状态找规律从特殊推一般 - -b 基本写一下n=1、2、3、4就可以懂了
然后就是代码乱写 就能把题做对…
代码:
/*
ID: housera1
PROG: shuttle
LANG: C++
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<set>
#include<iostream>
using namespace std;
char now[50],fin[50],ch[2]={'B','W'};
int n;
bool over()
{
if(strcmp(now,fin)==0) return true;
return false;
}
int main()
{
int Debug=0;
if(!Debug)
{
freopen("shuttle.in","r",stdin);
freopen("shuttle.out","w",stdout);
}
int i,j,k,las,out;
scanf("%d",&n);
for(i=1;i<=n;i++) now[i]='W',fin[i]='B';
for(i=n+2;i<=2*n+1;i++) now[i]='B',fin[i]='W';
now[0]=fin[0]=now[2*n+2]=fin[2*n+2]='_';
now[n+1]=fin[n+1]='@';
//printf("%s\n",now);
printf("%d",n);
out=1;
swap(now[n],now[n+1]);
i=n;
j=1;
las=0;
//printf("%s\n",now);
for(;;)
{
if(over()) break;
if(out==20)
{
puts("");
out=0;
}
else printf(" ");
k=i+j*2;
if(k>=1&&k<=2*n+1&&now[k]==ch[las]&&(i==1||i==2*n+1||now[i-1]==now[i+1]||now[k]==fin[i]))
{
printf("%d",k);
swap(now[i],now[k]);
i=k;
}
else
{
k=i+j;
if(k>=1&&k<=2*n+1&&now[k]!=fin[k])
{
printf("%d",k);
swap(now[i],now[k]);
j*=-1;
i=k;
}
else
{
j*=-1;
k=i+j;
printf("%d",k);
swap(now[i],now[k]);
i=k;
}
las^=1;
}
out++;
//printf("%s\n",now);
}
puts("");
return 0;
}