14行代码AC——习题5-4 交换学生(Foreign Exchange, UVa 10763)——解题报告

励志用少的代码做高效的表达


题目(提交)链接→UVa-10763


本题为水题,因此侧重点由解题转向优化。

题意:判断第一列的数字是否与第二列的数字相同(乱序)。解题方向多样,值得探究:
1、map哈希表解法:定义map cnt;,其中cnt[i]表示学校i对应的人数增减变化量,若有人把学校i作为出发地,则cnt[i]--;若作为目的地,则cnt[i]++。最终若是每个学校变化量均为0,说明项目可行;否则不可行。特点:时间、空间复杂度皆为O(n),都是动态开辟,基数小。为上等解法。
2、vector+sort解法:用两个vector容器分别存储第一列和第二列的数据。输入完成后排序,if(v1 == v2),则YES。特点:时间复杂度为O(nlogn),空间复杂度为O(n),但动态开辟,基数小。为中等解法。
3、数组解法:开两个大数组a[50W]b[50W],置0,分别存储第一列和第二列的数字。如:输入2 3,则a[2]++,b[3]++;最后从头到尾遍历,if(a[i] != b[i]),则NO。
特点:时间、空间复杂度为O(n),但基数大(50w),为下等解法。


下等解法太差劲了,所以这里只给出中等、上等解法。

vector+sort解法:

#include
using namespace std;
int main() {
	int n; while((cin >> n) && n) {
		vector<int> v1, v2; 
		for(int i = 0; i < n; i++) {
			int x1; cin >> x1; v1.push_back(x1);
			int x2; cin >> x2; v2.push_back(x2);
		}
		sort(v1.begin(),v1.end()); sort(v2.begin(),v2.end());
		cout << ((v1 == v2) ? "YES\n" : "NO\n"); 
	} 
	return 0;
} 

map哈希表映射解法:

#include
using namespace std;
int n, a, b;
int main() {
	while(cin >> n && n != 0) {
		map<int, int> cnt;			//每个学校对应的人数增减变化量
		for(int i = 0; i < n; i++) {
			cin >> a >> b;
			cnt[a]--;  cnt[b]++;	//分别代表出去与近来。 
		} 
		bool isWork = true;			//标记是否可行
		for(auto p : cnt) 
			if(p.second != 0) {
				isWork = false;
				break;
			}
		cout << (isWork ? "YES\n" : "NO\n");  
	}
	return 0;
}

天空不会永远阴暗,当乌云退散的时候,蓝天上灿烂的阳光就会照亮大地,青草照样会鲜绿无比,花朵仍然会蓬勃开放。                    ——《平凡的世界》

你可能感兴趣的:(算法竞赛与入门经典,C++与STL入门,c++)