C++ vector的使用及一道模板题 The Blocks Problem

写在前面

作为一个从Pascal转型成C++的蒟蒻,听说C++有很多很厉害的STL容器,于是写写模板题熟悉一下,故先写了这个含vector的模板题。下面先简单介绍一下vector的使用。

一、何为vector?

vector是一个C++中的一个可以实现自动增长的对象数组的一个模板类(大概就是个动态数组),如果数据不大的话使用起来十分方便省事,当然数据太大的话查找效率会低很多。。

二、初始化

首先,你要写个头文件:

#include <vector>

其次,初始化一个vector有几种形式:

1) vector<int> a(5); 
定义了5个整型元素的向量a,无初值,其值不知道。
(2) vector<int> a(5,100); 
定义了5个整型元素的向量a,且每个元素的初值为1003) vector<int> a(b); 
用b向量来创建向量a,整体复制性赋值
(4) vector<int> a(b.begin(),b.begin+5); 
定义了向量a为b中第0个到第4个元素(计数从0开始)
(5int b[3]={1,2,3};
		vector<int> a(b,b+3); 
从b数组中获得向量a中每个元素对应的初值
三、一些功能
1.添加/插入元素
  • 在a最后添加元素xa.push_back(x);
  • 一些插入操作
1)a.insert(a.begin()+1,x); 
在a的第1个元素(从第0个算起)的位置插入数值x
(2)a.insert(a.begin()+1,n,x); 
在a的第1个元素(从第0个算起)的位置插入n个数,值均为x
(3)a.insert(a.begin()+1,b+3,b+6); 
b为一个数组,在a的第1个元素(从第0个算起)的位置插入b的第3至第5个元素
2.删除元素
  • 将a清空a.clear();
  • 删除a中最后一个元素a.pop_back();
  • 删除操作
a.erase(a.begin()+1,a.begin()+3);
删除a中第1个(从第0个算起)到第2个元素
三、其他常用的表达
1)a.back(); 
返回a的最后一个元素
(2)a.front(); 
返回a的第一个元素
(3)a[i]; 
返回a的第i个元素,当且仅当a[i]存在
(4)a.empty(); 
判断a是否为空,空则返回TRUE,非空则返回FALSE
(5)a.size(); 
返回a中元素的总个数
(6)a.capacity(); 
返回a在内存中总共可以容纳的元素个数
······

注意
必须a[i]存在元素才能使用a[i]形式,否则会报错!
 
PS:还有一些其他的函数,因为我觉得用得比较少,所以就不予列举了QUQ

四、典例题目

是时候亮出这道模板题了!
From:UVaOJ 101
或者也可以在这评测:VJudge评测

(英文不好真的读题目都费劲)

The Blocks Problem

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:
在这里插入图片描述
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:

五、题目分析

就是有n个小方块编号为0到n-1,你需要通过四个操作来判断最终的叠放状态。

  • move a onto b
    把a和b上面所有的块全部放回原来对应的最初的列上,再把a放在b上;
  • move a over b
    把a上面所有的块全部放回原来对应的最初的列上,再把a放在b所对应的那列的最顶端;
  • pile a onto b
    把b上面所有的块全部放回原来对应的最初的列上,再把a及a以上的部分全部放在b上;
  • pile a over b
    把a及a以上的部分全部放在b所对应列的最顶端;
  • quit
    结束整个程序

大致就是用vector来模拟这0~n-1的“列”的情况,运用一些上面的基础vector用法就行了,需要注意的是,当a和b相等或者a和b本身就在同一列的时候,命令无效。

所以准备好屠杀这道题了吗?

六、贴个代码
#include <bits/stdc++.h>
using namespace std;

const int maxn=30;
int n,x,y;
int px,py,hx,hy;
vector <int> pos[maxn];//定义vector

void Block_delete(int p,int h,bool w)
{
	while (pos[p].size()!=(h+1)){
		int k=pos[p].back();
		pos[p].pop_back();
	if (w==1) pos[k].push_back(k);
	}
}

void findp(int x,int& p,int& h)
{
	for (p=0;p<n;p++)
		for (h=0;h<pos[p].size();h++)
			if (x==pos[p][h]) return;
}

bool judge(int x,int y)
{
	if (x==y) return false;
	if (px==py) return false;
	return true;
}

void Move_onto(int x,int y)
{
	Block_delete(px,hx,1);
	Block_delete(py,hy,1);
	pos[py].push_back(x);
	pos[px].pop_back();
}

void Move_over(int x,int y)
{
	Block_delete(px,hx,1);
	pos[py].push_back(x);
	pos[px].pop_back();	
} 

void Pile_onto(int x,int y)
{
	Block_delete(py,hy,1);
	for (int i=hx;i<pos[px].size();i++)
		pos[py].push_back(pos[px][i]);
	Block_delete(px,hx,0);
	pos[px].pop_back();
}

void Pile_over(int x,int y)
{
	for (int i=hx;i<pos[px].size();i++)
		pos[py].push_back(pos[px][i]);
	Block_delete(px,hx,0);
	pos[px].pop_back();
}

int main()
{
	cin>>n;
	for (int i=0;i<n;i++)
		pos[i].push_back(i);
	string change,way;
	cin>>change;
	while (change!="quit"){
		cin>>x>>way>>y;
		findp(x,px,hx);
		findp(y,py,hy);
		if (judge(x,y)){
			if (change=="move"&&way=="onto") Move_onto(x,y);
			if (change=="move"&&way=="over") Move_over(x,y);
			if (change=="pile"&&way=="onto") Pile_onto(x,y);
			if (change=="pile"&&way=="over") Pile_over(x,y);
		}
		cin>>change;
	}
	for (int i=0;i<n;i++){
		cout<<i<<":";
		for (int j=0;j<pos[i].size();j++)
			cout<<" "<<pos[i][j];
		cout<<endl;
	}
	return 0;
}

后话

体育课提前下课后来到机房,想起之前有一套全是关于STL的一些模板题,就对着网上的vector学习了一番,那么现在ZZY就大概明白了vector的基本操作了。

所以,我现在应该去做Arduino结课作业 睡觉了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值