您的位置:首页 > 其它

[UVA512]Spreadsheet Tracking[模拟][STL]

2015-07-22 13:24 579 查看
题目链接:[UVA512]Spreadsheet Tracking[模拟][STL]

题意分析:给出一个电子表格,进行若干次操作,然后进行若干次询问,每次询问输出单元格内容从哪里变到哪里,没有则输出消失了。其中,EX代表交换两个单元格。其它操作后面都会跟一个数字,代表需要操作的行或列的号码。例如:<command> A x1 x2 x3...xa 插入或删除xi行或列(DC-删除列,DR-删除行,IC-插入列,IR-插入行)

解题思路:我们可以用一个二维数组保存原来的表格,每次查询遍历这个二维数组即可。然后使用vector< vector<int> >来保存要操作的单元格。vector有提供删除(erase)和插入(insert)操作,所以本题用这个会很方便。(注意每个结果间的需要有空行,末位不需要)。另外,由于每次操作要进行多个行或列的插入或删除,所以得从外往里进行操作,也就是号码大的先操作(因为插入或删除会影响之后单元格的下标却不影响之前的)。

个人感受:这次模拟题把各种操作用函数给实现,整个代码没有之前的那么魔性了,debug的时候也方便了不少。多看看别人的代码风格果然棒棒哒~不过我还是debug这题了好久,vector用的很不熟练呀~

具体代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
using namespace std;
typedef vector< vector<int> > tvv;

int sheet[60][60]; //保存原来的表格 
int num[15];       //保存操作数后面要删除的号码 

void init(int& r, int& c, tvv& v)   //给每个单元格赋上数字(注意:这题我的单元格下标是从1开始,操作用的vector下标是0开始。) 
{
	int num = 0;
	for (int i = 1; i <= r; ++i)
		for (int j = 1; j <= c; ++j)
		{
			++num;
			sheet[i][j] = num;
			v[i - 1].push_back(num);
		}
}

void find(int x, int y, tvv& v) //查找单元格 
{
	printf("Cell data in (%d,%d) ", x, y);
	for (int i = 0; i < v.size(); ++i)
		for (int j = 0; j < v[i].size(); ++j)
		{
			if (v[i][j] == sheet[x][y])
			{
				printf("moved to (%d,%d)\n", i + 1, j + 1);
				return;
			}
		}
	puts("GONE");
}

void op_dr(int& n, tvv& v) //DR操作 
{
	int x;
	for (int i = 0; i < n; ++i)
	{
		x = num[i];
		v.erase(v.begin() + x - 1);
	}
}

void op_ir(int& n, tvv& v) //IR操作 
{
	int x;
	for (int i = 0; i < n; ++i)
	{
		x = num[i];
		v.insert(v.begin() + x - 1, vector<int>(v[0].size(), 0));
	}
}

void op_dc(int& n, tvv& v) //DC操作 
{
	int x;
	for (int i = 0; i < n; ++i)
	{
		x = num[i];
		for (int j = 0; j < v.size(); ++j)
		{
			v[j].erase(v[j].begin() + x - 1);
		}
	}
}

void op_ic(int& n, tvv& v) //IC操作 
{
	int x;
	for (int i = 0; i < n; ++i)
	{
		x = num[i];
		for (int j = 0; j < v.size(); ++j)
		{
			v[j].insert(v[j].begin() + x - 1, 0);
		}
	}
}

bool cmp(int a, int b)
{
	return a > b;
}

int main()
{
#ifdef LOCAL
	freopen("C:\\Users\\apple\\Desktop\\in.txt", "r", stdin);
#endif
	int r, c, cnt = 0;
	int d, q;
	while (cin >> r >> c && (r || c))
	{
		tvv v(r);
		init(r, c, v);
		cin >> d;
		string op;
		int n;
		for (int i = 0; i < d; ++i)
		{
			cin >> op >> n;
			if (op == "EX") 
			{
				for (int i = 0; i < 3; ++i) cin >> num[i];
				swap(v[n - 1][num[0] - 1], v[num[1] - 1][num[2] - 1]);
			}
			else 
			{
				for (int i = 0; i < n; ++i) cin >> num[i];
				sort(num, num + n, cmp);   //对特定的行或列号码进行操作是同时进行的,所以必须从号码大的开始操作 
				if (op == "DR")	op_dr(n, v);
				if (op == "DC") op_dc(n, v);
				if (op == "IC")	op_ic(n, v);
				if (op == "IR")	op_ir(n, v);
			}
		}
		
		if (cnt > 0) putchar('\n');
		printf("Spreadsheet #%d\n", ++cnt);
		
		cin >> q;
		for (int i = 0; i < q; ++i)
		{
			int x, y;
			cin >> x >> y;
			find(x, y, v);
		}
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: