初学acmer--读《算法竞赛入门经典》笔记 p110-111 Uva101

来源:互联网 发布:华为云计算视频百度云 编辑:程序博客网 时间:2024/04/29 17:27

题目:给你n个方块,有四种操作:

            1.move a onto b,把a和b上面的方块都放回原来位置,然后把a放到b上面;

            2.move a over b,把a上面的放回原处,然后把a放在b所在的方块堆的上面;

            3.pile a onto b,把b上面的放回原来位置,然后把a和a上面的方块整体放到b上面;

            4.pile a over b,把a和a上面的方块整体放到b所在堆的上面。

样例输入:

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 

样例输出:

0: 0 
1: 1 9 2 4 
2: 
3: 3 
4: 
5: 5 8 7 6 
6: 
7: 
8: 
9:


分析:这一题在理解了题意后,选择正确合适的数据结构就显得尤为重要。由于每个木块堆的高度不确定,所以用vector来保存就很合适,而木块的堆数不止一个且不确定,所以可以定义vector的数组,即定义vector<int> pile[maxn]。此时vector就像一个二维数组,只是第一维的大小是固定的,但是第二维的大小是可以改变的。vector是一个不定长的数组,可以用clear()来清空,resize()来改变长度,用push_back()和pop_back()在尾部添加和删除元素,用empty()测试是否为空,vector之间可以直接赋值或者作为函数的返回值,和int,char等普通数据类型一样。


下面贴代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
using namespace std;
const int maxn=30;
int n;
 vector<int> p[maxn];              //①

void find_blocks(int a,int &pa,int &ha)    // ③
{
    for(pa=0;pa<n;pa++)
    {
        for(ha=0;ha<p[pa].size();ha++)
        {
            if(a==p[pa][ha]) return;
        }
    }
}
void clear_blocks(int p1,int h)
{
    for(int i=h+1;i<p[p1].size();i++)
    {
        int t=p[p1][i];
        p[t].push_back(t);
    }
    p[p1].resize(h+1);
}
void pile_onto(int pa,int pb,int ha)
{
    for(int i=ha;i<p[pa].size();i++)
    {
        p[pb].push_back(p[pa][i]);
    }
    p[pa].resize(ha);
}
int  main()
{
    int a,b;
    cin>>n;
    string s1,s2;
    for(int i=0;i<n;i++)
    {
        p[i].push_back(i);
    }
    while(cin>>s1>>a>>s2>>b)
    {
        int pa,pb,ha,hb;
        find_blocks(a,pa,ha);
        find_blocks(b,pb,hb);
        if(pa==pb) continue;
        if(s2=="onto") clear_blocks(pb,hb);
        if(s1=="move") clear_blocks(pa,ha);       //②

        pile_onto(pa,pb,ha);
    }
    for(int i=0;i<n;i++)
    {
        cout<<i<<':';
        for(int j=0;j<p[i].size();j++)
        {
            cout<<p[i][j];
        }
        cout<<endl;
    }
}


ps:①:由于vector在main函数和其他函数都要用到,所以将其定义为全局比较方便

②:题目中一共4种指令,如果对它们都写一个代码,就很麻烦,更好的方法就是提取指令之间的共同点,将相同的操作用一个函数来表示,从而减少代码量

③:由于要改变的值不止一个,所以可以采用引用的方式返回调用者,不过要注意的是,在函数中for语句中不能再习惯性的打上(int pa....)

阅读全文
0 0
原创粉丝点击