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("\n");
    }
}

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;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章