题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=832
题意:2N个字符串两两合并,构成N个相同的字符串,输出这个字符串
分析:要能构成N个相同的字符串,假设其长度为L,则必须每个字符串s[i]都得有一个长度为L-s[i].size()的伙伴。一开始从P个最长的字符串中选一个,从Q个最短的字符串中选一个,进行合并,检测这个合并的结果能不能构成N个,如果能则找到,如果当前的字符串已经不是最长或者最短的了,说明最长的P个和最短的Q个都不能结合,肯定没有了就。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
struct CompareLen{
bool operator()(const string& a, const string& b){
return a.size() < b.size();
}
} comparator;
int N;
string s[150];
bool use[150] = {0};
bool input()
{
int i = 0;
while(getline(cin, s[i])){
if(s[i].empty()) break;
++i;
}
N = i;
return i > 0;
}
bool check(const string& t, int i)
{
if(i == N) return true;
if(use[i]) return check(t, i+1);
size_t tlen = t.size(), slen;
for(int j = i+1; j < N; ++j){
slen = s[i].size() + s[j].size();
if(slen < t.size()) continue;
if(slen > tlen) return false;
if(s[i] + s[j] == t || s[j] + s[i] == t){
use[i] = use[j] = true;
if(check(t, i+1)) return true;
use[i] = use[j] = false;
}
}
return false;
}
void work()
{
sort(s, s + N, comparator);
string t;
for(int i = 0; i < N; ++i){
for(int j = N-1; j > i; --j){
bool found = false;
use[i] = use[j] = true;
found = check(t = s[i] + s[j], 0) || check(t = s[j] + s[i], 0);
use[i] = use[j] = false;
if(found){
cout << t << "\n";
return;
}
}
}
}
int main()
{
while(input()) work();
return 0;
}