uva 101 - The Blocks Problem

题意  copy的 

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在同一堆積木中,那麼這樣的動作算是不合法的。所有不合法的動作應該被忽略,也就是對各積木均無改變。

题目本身不难就是题意不好理解
这道题可以用栈模拟   我用的是数组模拟的

#include<cstdio>
#include<cstring>
using namespace std;
const  int maxn = 30;
int num[maxn][maxn];
int visit[maxn];
int N;
/*这两块积木在同一堆返回1,否者返回0*/
int Judge(int a, int b)
{
    int i,j,x,y;
    for(i = 0; i < N; i++)
        for(j = 0;j < N; j++)
    {
        if(num[i][j]==a) x = i;
        if(num[i][j]==b) y = i;
    }
    if(x == y)return 1;
    return 0;
}

void Index(int& i,int& j,int a)//找到积木在数组的哪个位置
{
    int flag = 1;
    for(i = 0; i < N&&flag; i++)
        for(j = 0;j < N&&flag; j++)
        if(num[i][j]==a)flag = 0;
    --i;
    --j;
}

void Removing(int i,int j)//把第i行j列后的元素放到初始位置
{
    j++;
    for( ; num[i][j]!=-1; j++)
    {
        visit[i]--;
        int t = num[i][j];
        num[i][j] = -1;
        num[t][0] = t;
        visit[t]++;
    }
}

void move_onto(int a, int b)
{
    int i, j, m, n;
    i = j = m = n =0;
    Index(m,n,b);
    Index(i,j,a);
    Removing(i,j);
    Removing(m,n);
    num[m][++n] = num[i][j];
    visit[m]++;
    visit[i]--;
    num[i][j] = -1;
}

void move_over(int a, int b)
{
    int i, j, m, n;
    i = j = m = n = 0;
    Index(i,j,a);
    Index(m,n,b);
    Removing(i,j);
    num[m][++visit[m]] = num[i][j];
    num[i][j] = -1;
    visit[i]--;
}

void pile_onto(int a, int b)
{
    int i, j, m, n;
    i = j = m = n = 0;
    Index(i,j,a);
    Index(m,n,b);
    Removing(m,n);
    for( ; num[i][j]!=-1;j++)
    {
        num[m][++visit[m]] = num[i][j];
        num[i][j] = -1;
        visit[i]--;
    }
}

void pile_over(int a, int b)
{
    int i, j, m, n;
    i = j = m = n = 0;
    Index(i,j,a);
    Index(m,n,b);
    for( ; num[i][j]!=-1;j++)
    {
        num[m][++visit[m]] = num[i][j];
        num[i][j] = -1;
        visit[i]--;
    }
}

int main()
{
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    #endif // LOCAL
    while(scanf("%d",&N)!=EOF)
    {
        memset(num,-1,sizeof(num));
        memset(visit,0,sizeof(visit));
        for(int i = 0;i < N; i++)
            num[i][0] = i;
        char s1[6], s2[6];
        int number1,number2;
        while(scanf("%s",s1))
        {
            if(s1[0]=='q')break;
            scanf("%d %s %d",&number1,s2,&number2);
            if(Judge(number1,number2))continue;
            if(s1[0]=='m'&&s2[1]=='n')move_onto(number1,number2);
            if(s1[0]=='m'&&s2[1]=='v')move_over(number1,number2);
            if(s1[0]=='p'&&s2[1]=='n')pile_onto(number1,number2);
            if(s1[0]=='p'&&s2[1]=='v')pile_over(number1,number2);
        }
        for(int i = 0;i < N; i ++)
        {
            printf("%d:",i);
            for(int j = 0; num[i][j]!=-1;j++)
            printf(" %d",num[i][j]);
            printf("\n");
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值