uva-101 && poj 1208 The Blocks Problem (模拟栈)

来源:互联网 发布:下载机械制图软件 编辑:程序博客网 时间:2024/06/06 15:50

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18191

题意:   下面的步骤看别人的,

機器手臂有以下幾種合法搬積木的方式(a和b是積木的編號):
move a onto b
在將a搬到b上之前,先將a和b上的積木放回原來的位置(例如:1就放回1的最開始位罝)
move a over b
在將a搬到b所在的那堆積木之上之前,先將a上的積木放回原來的位罝(b所在的那堆積木不動)
pile a onto b
將a本身和其上的積木一起放到b上,在搬之前b上方的積木放回原位
pile a over b
將a本身和其上的積木一起搬到到b所在的那堆積木之上
quit
動作結束

前四個動作中若a=b,或者a, b在同一堆積木中,那麼這樣的動作算是不合法的。所有不合法的動作應該被忽略,也就是對各積木均無改變

 

思路:就是一个模拟栈的问题,对自己还是有一点难度,折腾了几天,最后在poj找到测试数据,才摆脱re的折磨。基础差,各种差!!!
pile[i][i]表示第i堆第i个数,in[i]表示第i堆的总数,q[i]表示第i张牌的当前位置,模拟就好了,注意细节。

奉上一组poj上的测试数据:

9
move 4 onto 1
move 8 onto 3
move 7 onto 8
move 8 onto 1
move 2 onto 6
move 1 over 6
move 3 onto 7
move 8 onto 3
pile 2 onto 3
move 4 onto 5
move 6 onto 4
pile 3 onto 4
quit

#include <iostream>#include <cstdio>#include <cmath>#include <vector>#include <cstring>#include <string>#include <algorithm>#include <string>#include <set>#include <functional>#include <numeric>#include <sstream>#include <stack>#include <map>#include <queue>#define CL(arr, val)    memset(arr, val, sizeof(arr))#define ll long long#define inf 0x7f7f7f7f#define lc l,m,rt<<1#define rc m + 1,r,rt<<1|1#define pi acos(-1.0)#define L(x)    (x) << 1#define R(x)    (x) << 1 | 1#define MID(l, r)   (l + r) >> 1#define Min(x, y)   (x) < (y) ? (x) : (y)#define Max(x, y)   (x) < (y) ? (y) : (x)#define E(x)        (1 << (x))#define iabs(x)     (x) < 0 ? -(x) : (x)#define OUT(x)  printf("%I64d\n", x)#define lowbit(x)   (x)&(-x)#define Read()  freopen("a.txt", "r", stdin)#define Write() freopen("dout.txt", "w", stdout);#define N 100005using namespace std;const int len = 100;int pile[len][len],in[len],q[len]; //pile[i][i]表示第i堆牌第i张,in表示第i堆牌总数,q表示第i张牌的当前位置int pd(int x,int y) //判断x跟y在不在同一堆{    if(q[x]==q[y]) return 1;  //判断当前位置  是不是在同一堆即可    return 0;}void solve(int x) //将 x上的积木放回原来的位置 不包括x{    int i,ans,y,z;   //从x这一堆  从上往下找    ans=in[q[x]]; //当前堆 积木总数    y=q[x]; //当前堆编号    for(i=ans;pile[y][i]!=x;i--)    {        z=pile[y][i]; //当前堆需要移动的积木编号        q[z]=z; //当前积木移到初始位置,那么 当前积木移动后当前位置变为自身编号        pile[z][++in[z]]=z; //重新存储        in[y]--;  //当前堆减1    }}void solve2(int x,int y) //将 x本身和其上的积木一起放到y上,并且按顺序放{    int i,ans=0,z,y1,y2;    for(i=in[q[x]];pile[q[x]][i]!=x;i--)    {        ans++;  //求出x在当前堆的位置    }    z=in[q[x]];  //当前堆 总数    y1=q[x];//当前堆 编号       for(i=z-ans;i<=z;i++)  //移动    {        q[pile[y1][i]]=q[y]; //把积木的当前位置改掉        pile[q[y]][++in[q[y]]]=pile[y1][i]; //移动        in[y1]--; //总数减 1    }}int main(){    //Read();  //文件读取    int n,i,j;    char s[30],a[10],b[10];    int c,d;    while(scanf("%d",&n)!=EOF)  //读入n,代表有n张牌    {        getchar();        CL(pile,0); //清空数组        CL(q,0);        CL(in,0);        for(i=0;i<n;i++) //初始化        {            in[i]=1;            q[i]=i;            pile[i][1]=i;        }        while(1)        {            gets(s);            if(s[0]=='q') break;            sscanf(s,"%s %d %s %d",a,&c,b,&d);            if(c==d||pd(c,d))   continue;            if(strcmp(a,"move")==0)            {                if(strcmp(b,"onto")==0)                {                    if(in[q[c]]>1)solve(c);                    if(in[q[d]]>1)solve(d);                    pile[q[d]][++in[q[d]]]=pile[q[c]][in[q[c]]--];                    q[c]=q[d];                }                else if(strcmp(b,"over")==0)                {                    if(in[q[c]]>1) solve(c);                    pile[q[d]][++in[q[d]]]=pile[q[c]][in[q[c]]--];                    q[c]=q[d];                }            }            else if(strcmp(a,"pile")==0)            {                if(strcmp(b,"onto")==0)                {                    if(in[q[d]]>1)solve(d);                    solve2(c,d);                }                else if(strcmp(b,"over")==0)                {                    solve2(c,d);                }            }        }        for(i=0;i<n;i++)        {            if(in[i]==0)            {                printf("%d:\n",i);            }            else            {                printf("%d:",i);                for(j=1;j<=in[i];j++)                {                    if(j!=in[i]) printf(" %d",pile[i][j]);                    else printf(" %d\n",pile[i][j]);                }            }        }    }    return 0;}

下面是别人用vector写的,比我的规范多了! 

#include <cstdio>#include <vector>#include <stack>using namespace std;const int MAXN = 30;vector<int> pile[MAXN];int pos[MAXN];const int MOVE = 0;const int PILE = 1;const int ONTO = 0;const int OVER = 1;void init(int n){    for(int i=0; i<n; i++){        pile[i].clear();        pile[i].push_back(i);        pos[i] = i;    }}bool ReadInstruct(int &insA, int &insB, int &x, int &y){    char s1[10];    scanf("%s", s1);    if(s1[0] == 'q') return false;    if(s1[0] == 'm') insA = MOVE;    else insA = PILE;    scanf("%d", &x);    scanf("%s", s1);    if(s1[1] == 'n') insB = ONTO;    else insB = OVER;    scanf("%d", &y);    return true;}void PrintPile(int n){    for(int i=0; i<n; i++){        printf("%d:", i);        for(int j=0; j<pile[i].size(); j++){            printf(" %d", pile[i][j]);        }        printf("\n");    }}void ReturnAbove(int x){    int px = pos[x];    while(1){        int y = pile[px].back();        if(y == x) break;        pile[px].pop_back();        pile[y].push_back(y);        pos[y] = y;    }}void StoreAbove(stack<int> &stk, int x){    int px = pos[x];    while(1){        int y = pile[px].back();        pile[px].pop_back();        stk.push(y);        if(y == x) break;    }}void MoveTo(stack<int>& stk, int y) //move stk to y{    int py = pos[y];    while(!stk.empty()){        int x = stk.top(); stk.pop();        pos[x] = py;        pile[py].push_back(x);    }}int main(){    //freopen("in", "r", stdin);    int n;    scanf("%d", &n);    init(n);    int insA, insB, a, b;    while(1){        if(ReadInstruct(insA, insB, a, b) == false)            break;        if(pos[a] == pos[b]) continue;        if(insA == MOVE) //move            ReturnAbove(a);        if(insB == ONTO) //onto            ReturnAbove(b);        stack<int> stk;        StoreAbove(stk, a);        MoveTo(stk, b);    }    PrintPile(n);}


 

 

 

 

0 0