2019/02/17训练日记

就是这个题!!!!!

Many areas of Computer Science use simple, abstract domains for both analytical and empirical studies.
For example, an early AI study of planning and robotics (STRIPS) used a block world in which a robot
arm performed tasks involving the manipulation of blocks.
In this problem you will model a simple block world under certain rules and constraints. Rather
than determine how to achieve a specified state, you will “program” a robotic arm to respond to a
limited set of commands.
The problem is to parse a series of commands that instruct a robot arm in how to manipulate blocks
that lie on a flat table. Initially there are n blocks on the table (numbered from 0 to n − 1) with block
bi adjacent to block bi+1 for all 0 ≤ i < n − 1 as shown in the diagram below:
Initial Blocks World
The valid commands for the robot arm that manipulates blocks are:
• move a onto b
where a and b are block numbers, puts block a onto block b after returning any blocks that are
stacked on top of blocks a and b to their initial positions.
• move a over b
where a and b are block numbers, puts block a onto the top of the stack containing block b, after
returning any blocks that are stacked on top of block a to their initial positions.
• pile a onto b
where a and b are block numbers, moves the pile of blocks consisting of block a, and any blocks
that are stacked above block a, onto block b. All blocks on top of block b are moved to their
initial positions prior to the pile taking place. The blocks stacked above block a retain their order
when moved.
• pile a over b
where a and b are block numbers, puts the pile of blocks consisting of block a, and any blocks
that are stacked above block a, onto the top of the stack containing block b. The blocks stacked
above block a retain their original order when moved.
• quit
terminates manipulations in the block world.
Any command in which a = b or in which a and b are in the same stack of blocks is an illegal
command. All illegal commands should be ignored and should have no affect on the configuration of
blocks.
Input
The input begins with an integer n on a line by itself representing the number of blocks in the block
world. You may assume that 0 < n < 25.
The number of blocks is followed by a sequence of block commands, one command per line. Your
program should process all commands until the quit command is encountered.
You may assume that all commands will be of the form specified above. There will be no syntactically
incorrect commands.
Output
The output should consist of the final state of the blocks world. Each original block position numbered
i (0 ≤ i < n where n is the number of blocks) should appear followed immediately by a colon. If there
is at least a block on it, the colon must be followed by one space, followed by a list of blocks that appear
stacked in that position with each block number separated from other block numbers by a space. Don’t
put any trailing spaces on a line.
There should be one line of output for each block position (i.e., n lines of output where n is the
integer on the first line of input).
Sample Input
10
move 9 onto 1
move 8 over 1
move 7 over 1
move 6 over 1
pile 8 over 6
pile 8 over 5
move 2 over 1
move 4 over 9
quit
Sample Output
0: 0
1: 1 9 2 4
2:
3: 3
4:
5: 5 8 7 6
6:
7:
8:
9:

思路是写一个结构体表示每个数的横纵坐标,用模拟法,每次操作只改变坐标,最后按照坐标输入进一个二维数组,再按题目要求输出。虽然这是STL训练我真的没找到可以使用的容器,所以去网上着大佬的代码分析一下,弥补自己的不足。

我的代码
#include<cmath>
#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;
struct zb
{
  int x;
  int y;
};
int c[30][30]={9999};
zb w[30];
int n;
void moon(int a,int b);
void moov(int a,int b);
void pion(int a,int b);
void piov(int a,int b);
int main()
{
    string s;
    string s1;
    int z1;
    int z2;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        w[i].x=i;
        w[i].y=1;
        for(int t=0;t<=n;t++)
        {
            c[i][t]=9999;
        }
    }
    while(cin>>s)
    {
        if(s=="quit") break;
        cin>>z1;
        cin>>s1;
        cin>>z2;
        if(w[z1].x==w[z2].x) continue;
        if(s=="move")
        {
            if(s1=="onto")
            {
                moon(z1,z2);
            }
            if(s1=="over")
            {
                moov(z1,z2);
            }
        }
        if(s=="pile")
        {
            if(s1=="onto")
            {
                pion(z1,z2);
            }
            if(s1=="over")
            {
                piov(z1,z2);
            }
        }
    }
    for(int i=0;i<n;i++)
    {
        c[w[i].x][w[i].y]=i;
    }
    for(int i=0;i<n;i++)
    {
        cout<<i<<':';
        for(int t=1;t<=n;t++)
        {
            if(c[i][t]!=9999)cout<<' '<<c[i][t];
        }
        cout<<endl;
    }
}
void moon(int a,int b)
{
    for(int i=0;i<n;i++)
    {
        if(w[i].x==w[a].x)
        {
            if(w[i].y>w[a].y)
            {
                w[i].x=i;
                w[i].y=1;
            }
        }
        if(w[i].x==w[b].x)
        {
            if(w[i].y>=w[b].y)
            {
                w[i].x=i;
                w[i].y=1;
            }
        }
    }
    w[a].x=w[b].x;
    w[a].y=w[b].y+1;
}
void moov(int a,int b)
{
    int mid=w[b].y;
    int xid=w[a].y;
    int xi=w[a].x;
    for(int i=0;i<n;i++)
    {
        if(w[i].x==xi)
        {
            if(w[i].y>xid)
            {
                w[i].x=i;
                w[i].y=1;
            }
        }
         if(w[i].x==w[b].x)
        {
            if(w[i].y>mid) mid=w[i].y;
        }
    }
    w[a].x=w[b].x;
    w[a].y=mid+1;
}
void pion(int a,int b)
{
    int xid=w[a].y;
    int xi=w[a].x;
    int yid=w[b].x;
     for(int i=0;i<n;i++)
    {
        if(w[i].x==w[b].x)
        {
            if(w[i].y>w[b].y)
            {
                w[i].x=i;
                w[i].y=1;
            }
        }
        if(w[i].x==xi)
        {
            if(w[i].y>=xid)
            {
                w[i].y=w[i].y+1+w[b].y-xid;
                w[i].x=w[b].x;
            }
        }

    }
}
void piov(int a,int b)
{
    int mid=w[b].y;
    int xid=w[a].y;
    int xi=w[a].x;
    for(int i=0;i<n;i++)
    {
         if(w[i].x==w[b].x)
        {
            if(w[i].y>mid) mid=w[i].y;
        }
    }
    for(int i=0;i<n;i++)
    {
        if(w[i].x==xi)
        {
            if(w[i].y>=xid)
            {
                w[i].y=w[i].y+mid+1-xid;
                w[i].x=w[b].x;
            }
        }
    }
}

大佬的代码

#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<iostream>
using namespace std;

const int maxn = 30;
int n;
vector<int>pile[maxn];//每个pile[i]是一个vector

void find_block(int a,int& p,int& h)//找到木块所在的pile和height。
{
    for(p=0;p<n;p++)
    {
        for(h=0;h<pile[p].size();h++)
        {
            if(pile[p][h]==a)
            {
                return ;
            }
        }
    }
}

//把第p堆高度为h的木块上方的木块都移回原位
void clear_above(int p,int h)
{
    for(int i=h+1;i<pile[p].size();i++)
    {
        int b=pile[p][i];
        pile[b].push_back(b);//把木块b放回原位
    }
    pile[p].resize(h+1);//pile只应保留下标0~h的元素
}

//把第p堆高度为h及其上方所有的木块整体移动到p2堆的顶部
void pile_onto(int p,int h,int p2)
{
    for(int i=h;i<pile[p].size();i++)
    {
        pile[p2].push_back(pile[p][i]);
    }
    pile[p].resize(h);
}

void print()
{
    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("
");
    }
}

int main()
{
    int a,b;
    cin>>n;
    string s1,s2;
    for(int i=0;i<n;i++)
    {
        pile[i].push_back(i);
    }
    while(cin>>s1)
    {
        if(s1=="quit")break;
        cin>>a>>s2>>b;
        int pa,pb,ha,hb;
        find_block(a,pa,ha);
        find_block(b,pb,hb);
        if(pa==pb)continue;
        if(s2=="onto")
            clear_above(pb,hb);
        if(s1=="move")clear_above(pa,ha);
        pile_onto(pa,ha,pb);
    }
    print();
    return 0;
}
--------------------- 
作者:夜幕下的ACM之路 
来源:CSDN 
原文:https://blog.csdn.net/qq_32866009/article/details/52199634 
版权声明:本文为博主原创文章,转载请附上博文链接!

大佬采用了vector容器,使用了vector的成员函数,代码长度减少了很多,首先定义了vector< int >型的数组,数组的下标可作为堆号.定义vector的数组是之间没有遇到的,也是不会使用的。

!!!知识点

1.可以定义vector< type >型的数组。
2.vector< type >1.push_back(vector< type >2),vector< type >2元素放到vector< type >1后。

resize(),设置大小(size); reserve(),设置容量(capacity); size()是分配容器的内存大小,而capacity()只是设置容器容量大小,但并没有真正分配内存。 打个比方:买了一个新房子,新房子里可以放3张床reserve(3),这是说房子的容量是最多放3张床,但是屋里并不是有三张床,二resize(3),房里安装了3张床,此时房里的床可以使用了。
reserve为容器预留足够的空间,避免不必要的重复分配,分配空间大于等于函数的参数,影响capacity。
resize调整容器中有效数据区域的尺寸,如果尺寸变小,原来数据多余的截掉。若尺寸变大,不够的数据用该函数第二个参数填充,影响size。
由于vector是顺序容器,在内存中分配了一块连续的存储空间。为了保证动态添加元素的高效率,因此必须预先为vector分配一段空间,这个空间就是capacity。
而容器中元素的个数就是size(),在容器中,capacity总是大于等于 size;

原文地址:https://www.cnblogs.com/lunatic-talent/p/12799094.html