USACO Section 4.4 Shuttle Puzzle

来源:互联网 发布:win10 淘宝激活码 编辑:程序博客网 时间:2024/05/20 04:12

题意:

2n个棋子排在一条长2n+1的线上  白色全在最左端黑色全在右端  每次操作可以移动一个棋子到空位或者跳一个棋子到空位(最多跳一个棋子)  问最少多少操作可以使白色全在右端黑色全在左端


思路:

最优的策略可以想出来  就是先把棋子排成黑白交错  然后不断把黑的往左白的往右移

例子里的提示也足够想到策略  最主要是代码怎么写

我的做法就是乱搞…  反正写出状态找规律从特殊推一般 - -b  基本写一下n=1、2、3、4就可以懂了

然后就是代码乱写  就能把题做对…


代码:

/*ID: housera1PROG: shuttleLANG: 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;}


0 0