POJ 1208 TheBlocks Problem (模拟+队列)

来源:互联网 发布:淘宝做的好的鲨鱼复刻 编辑:程序博客网 时间:2024/05/20 06:06

题意:NBlock,有四种操作可以相互移动Block使得他们叠起来。给出操作序列,求最后的状态。

Idea:模拟。

不算难,但是题意、一些细节要注意下。

 


#include <cstdio>#include <iostream>#include <fstream>#include <cstring>#include <string>#define OP(s) cout<<#s<<"="<<s<<" ";#define PP(s) cout<<#s<<"="<<s<<endl;using namespace std;static int s[300][300],h[300],pos[300];void remove(int pa,int a){    int i;    for (i = 1; i <= h[pa]; i++)        if (s[pa][i] == a) break;    for (; i < h[pa]; i++)        s[pa][i] = s[pa][i+1];    h[pa]--;}void moveonto(int a,int pb,int b){    int i;    for (i = 1; i <= h[pb]; i++)        if (s[pb][i] == b) break;    for (int j = h[pb]; j > i; j--) //j >= i        s[pb][j+1] = s[pb][j];    s[pb][i+1] = a;//s[pb][i] = a;    pos[a] = pb;    h[pb]++;}void moveover(int a,int pb){    s[pb][++h[pb]] = a;    pos[a] = pb;}void pileonto(int pa,int a,int pb,int b){    int i;    for (i = 1; i <= h[pa]; i++)        if (s[pa][i] == a) break;    int j;    for (j = 1; j <= h[pb]; j++)        if (s[pb][j] == b) break;    int sum = h[pa] - i + 1;    for (int k = h[pb]; k > j; k--)        s[pb][k+sum] = s[pb][k];    for (int k = j+1; i <= h[pa]; i++,k++)    {        int t = s[pa][i];        s[pb][k] = t;        pos[t] = pb;    }    h[pa] -= sum;    h[pb] += sum;}void pileover(int pa,int a,int pb,int b){    int i;    for (i = 1; i <= h[pa]; i++)        if (s[pa][i] == a) break;    int sum = h[pa] - i + 1;    for (; i <= h[pa]; i++)    {        int t = s[pa][i];        s[pb][++h[pb]] = t;        pos[t] = pb;    }    h[pa] -= sum;}int main(){    freopen("test.txt","r",stdin);    int N;    scanf("%d",&N);    for (int i = 0; i <= 30; i++)    {        s[i][1] = i;        h[i] = 1;        pos[i] = i;    }    string cmd;    int a,b,pa,pb;    while (cin>>cmd,cmd != "quit")    {        if (cmd == "move")        {            cin>>a>>cmd>>b;            pa = pos[a];            pb = pos[b];            if (pa == pb) continue;            if (cmd == "onto")            {                remove(pa,a);                moveonto(a,pb,b);            }            else            {                remove(pa,a);                moveover(a,pb);            }        }        else        {            cin>>a>>cmd>>b;            pa = pos[a];            pb = pos[b];            if (pa == pb) continue;            if (cmd == "onto")            {                pileonto(pa,a,pb,b);            }            else            {                pileover(pa,a,pb,b);            }        }    }    for (int i = 0; i < N; i++)    {        printf("%d:",i);        for (int j = 1; j <= h[i]; j++) printf(" %d",s[i][j]);        printf("\n");    }    return 0;}/*1/4开始以为是道简单题,没多想就去写了。1.开始题意给理解错了,把moveonto,A->B理解成了让a、b上其余的block都移动回最初的位置,题意其实是插入的意思;2.a->b 开始写成了把a移动到第b堆,事实上b所在的堆 != 第b堆。3.细节的把握,a-moveonto-b,a 是在b 的后面一个位置,而我写成了在b所在的位置总之,对于稍复杂的模拟题做的不尽人意,加油~*/


原创粉丝点击