/**
* 贪心题
* 思路:能否先找出所有可能的答案? 如果能找出所有可能的答案而且可能的情况很小的话,一一枚举也是很快的!
* 怎么找? 首先在每次输入的时候,就对所有字符串进行预处理。 用三维数组str来存数据,第一个方括号表示的是该字符串的长度,
* 中间的表示有2个这样长度的字符串(为什么只有2个,因为按照题意,必然是能够够成原文件的,同样长度的字符串,
* 只有可能是前面那半和后面那半两种可能。 这样在每次输入的时候就可以判断,如果相同的话就不存入数组,不同的话就存。
* 再然后就是找可能的答案,首先先找到最小长度和最大长度的字符串,因为这两种必能且只能是这两一起匹配成原文件!
* 所以如果说最小字符串有两个 a, b 那最大字符串必有2个c, d 那可能的答案只能是ab, ac, ba, bc
* 如果最小字符串只有一个,那更简单了, 只有可能是ab 或者 ba
* 这样就构造了可能的解空间,而且易正明肯定是完整的,也就是不会漏解
* 之后再找下一个适合的两种长度la, lb可以构造出原文件的,但注意la + lb 要等于 之前的最小长度加最大长度。
* 然后再根据之前的构造所有可能的情况与解空间对比,一样的那个就是原文件了!
*
* 这里最最关键的是,就是按照自己的算法写的时候, 一开始一直RE,我还以为数组不够大,一直改还是RE
* 找了好久才发现,忽略了一种当两种长度都相等的时候,也就是最小长度 等于 最大长度的时候! 而且,这个时候的两种字符串是相同的还是不同的!!
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
bool vis[300];
char anss[5][300];
char str[300][2][300];
int minLen, maxLen;
int gotAns() {
int i, secMin = minLen + 1, secMax = maxLen - 1;
for(i = secMin; i < 300; i ++) {
if(str[i][0][0] != '*') {
secMin = i;
break;
}
}
secMax = maxLen - (secMin - minLen);
char curAns[300];
for(i = 0; i < 4; i ++) {
strcpy(curAns, str[secMin][0]);
strcat(curAns, str[secMax][0]);
if(!strcmp(curAns, anss[i])) break;
if(str[secMin][1][0] != '*') {
strcpy(curAns, str[secMin][0]);
strcat(curAns, str[secMax][1]);
if(!strcmp(curAns, anss[i])) break;
strcpy(curAns, str[secMax][0]);
strcat(curAns, str[secMin][0]);
if(!strcmp(curAns, anss[i])) break;
strcpy(curAns, str[secMax][1]);
strcat(curAns, str[secMin][0]);
if(!strcmp(curAns, anss[i])) break;
} else {
strcpy(curAns, str[secMax][0]);
strcat(curAns, str[secMin][0]);
if(!strcmp(curAns, anss[i])) break;
}
}
return i;
}
void makeAns() {
strcpy(anss[0], str[minLen][0]);
strcat(anss[0], str[maxLen][0]);
if(str[maxLen][1][0] == '*') {
strcpy(anss[1], str[maxLen][0]);
strcat(anss[1], str[minLen][0]);
} else {
strcpy(anss[1], str[minLen][0]);
strcat(anss[1], str[maxLen][1]);
strcpy(anss[2], str[maxLen][0]);
strcat(anss[2], str[minLen][0]);
strcpy(anss[3], str[maxLen][1]);
strcat(anss[3], str[minLen][0]);
}
}
int main()
{
//freopen("in.txt", "r", stdin);
int n;
char cur[300];
scanf("%d", &n);
getchar();
for(int i = 0; i < n; i ++) {
int len;
if(i != 0) printf("\n");
else getchar();
memset(str, '*', sizeof(str));
memset(vis, false, sizeof(vis));
while(gets(cur) != NULL) {
if(!strcmp(cur, "")) break;
len = strlen(cur);
if(str[len][0][0] == '*') {
strcpy(str[len][0], cur);
} else if(strcmp(cur, str[len][0]) != 0) {
strcpy(str[len][1], cur);
}
int l, r;
for(l = 0; l < 300; l ++) {
if(str[l][0][0] != '*') {
minLen = l;
break;
}
}
for(r = 299; r >= 0; r --) {
if(str[r][0][0] != '*') {
maxLen = r;
break;
}
}
}
if(maxLen == minLen) {
strcpy(cur, str[maxLen][0]);
if(str[maxLen][1][0] != '*')
strcat(cur, str[maxLen][1]);
else
strcat(cur, str[maxLen][0]);
puts(cur);
continue;
}
makeAns();
puts(anss[gotAns()]);
}
return 0 ;
}
UVa 10132 - File Fragmentation 贪心+枚举
最新推荐文章于 2018-02-21 07:43:20 发布