您的位置:首页 > 其它

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

2017-09-27 10:55 309 查看
题目:给你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....)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: