UVa Problem 10132 File Fragmentation (文件还原) 排列组合+暴力

题目说每个相同文件(01串)都被撕裂成两部分,要求拼凑成原来的样子,如果有多种可能输出一种。

我标题写着排列组合,其实不是什么高深的数学题,只要把最长的那几个和最短的那几个凑一起,然后去用其他几个验证就行了,反正我的验证是非常暴力的,看起来。。。(其实加了个二维数组判定不是很吃复杂度)

代码:

#include <string>
#include <cstring>
#include <stdio.h>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 150;

string p[maxn];
int n, cnt, min, max;
bool flag, used[maxn];

bool cmp (string a, string b) {
	return a.size() < b.size();
}

bool check(string str) {
	for (int i = 0; i < cnt; i++)
		for (int j = 0; j < cnt; j++) {
			if (!used[i] && !used[j] && p[i] + p[j] == str)
				used[i] = used[j] = true;
		}//for
	for (int i = 0; i < cnt; i++)
		if (used[i] == false)
			return false;
	return true;
}

int main() {
	cin >> n;
	getline(cin, p[0]);
	getline(cin, p[0]);
	while(n--) {
		cnt = 0;
		while (getline(cin, p[cnt]) && !p[cnt].empty()) cnt++;
		sort(p, p + cnt, cmp);
		flag = false;
		for (int i = 0; !flag && p[i].size() == p[0].size(); i++)
			for (int j = cnt - 1; !flag && p[j].size() == p[cnt - 1].size(); j--) {
				memset(used, 0, sizeof(used));
				used[i] = used[j] = 1;
				if (check(p[i] + p[j])) {
					cout << p[i] + p[j] << endl;
					flag = true;
					break;
				}//if
				memset(used, 0, sizeof(used));
				used[i] = used[j] = 1;
				if (check(p[j] + p[i])) {
					cout << p[j] + p[i] << endl;
					flag = true;
					break;
				}//if
			}//for
		if (n)
			printf("\n");
	}//while
	return 0;
}



你可能感兴趣的:(ACM)