初学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....)
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....)
相关文章推荐
- 初学acmer--《算法竞赛入门经典》笔记(十)P54-56
- 初学acmer--读《算法竞赛入门经典》笔记(五)P41-45
- 初学acmer--读《算法竞赛入门经典》笔记(三)p27-34
- 初学acmer--读《算法竞赛入门经典》笔记(一)P12-23
- 初学acmer--读《算法竞赛入门经典》笔记(二) p25-27
- 初学acmer--读《算法竞赛入门经典》笔记(11)P61-65
- 算法竞赛入门经典第五章例题5-2 The Blocks Problem UVA - 101
- 初学acmer--《算法竞赛经典入门》笔记(九) P52-53
- 初学acmer--读《算法竞赛入门经典》笔记<四>(p36-41)
- 初学acmer--读《算法竞赛经典入门》笔记(六)p45-48
- UVA 101(p110)----The Blocks Problem
- 算法竞赛入门经典第三章3-12 Floating-Point Numbers UVA - 11809
- 序列代码UVa 111 History Grading (最长公共子序列)
- 算法竞赛入门经典第四章习题4-3 Othello UVA - 220
- UVA101木块问题
- [刷题]算法竞赛入门经典(第2版) 4-9/UVa1591 - Data Mining
- Python 初学笔记:os模块
- uva 111 History Grading(动态规划:LCS)
- 初学Matlab自学笔记记录
- UVA 101 The Blocks Problem