题目其实不算难。可以先把片段按长度排序,对于长度相同的则再按字符串比较,这样相同的片段就会在一起,从而可以大大减少不必要的搜索。
几次提交得到WA,于是自己构造5000组测试用例结果显示没有错。以为是zoj数据太刁钻,调了几个小时还是WA,最后终于发现是输入输出格式问题。。。坑爹!格式控制仍然是心中的痛哎
看上去很费时,其实搜索速度很快,提交通过时间0ms,内存276KB。
#include<fstream>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include "m_debug.h"
using namespace std;
string frag[300];
bool used[300];
string res; //result string
int len; //result string's length
int n; //片段总数量
class Less{
public:
bool operator()(const string &s1,const string &s2){
if(s1.length()<s2.length()) return true;
else if(s1.length()==s2.length() && s1<s2) return true;
else return false;
}
};
bool solve(int spos,int epos){
if(spos>=epos){
for(int i=epos;i<n;i++) if(used[i]==false) return false;
return true;
}
if(used[spos]){ while(spos<epos && used[spos]) spos++; return solve(spos,epos); } //frag[spos]在此前可能已经配对
used[spos] = true;
if(res==""){
for(int i=epos;frag[i].length()==frag[n-1].length();i--){
if(i<epos && frag[i]==frag[i+1]) continue; //剪枝,避免重复搜索
res = frag[spos] + frag[i];
used[i] = true; //暂时占用frag[i]
if(solve(spos+1,epos)) return true;
else{
res = frag[i] + frag[spos];
if(res!=frag[spos]+frag[i] && solve(spos+1,epos)) return true;
else used[i] = false; //释放frag[i]
}
}
}
else{
while(spos<epos && frag[spos].length()+frag[epos].length()>len) epos--;
if(spos==epos) return false;
for(int i=epos;i>spos&&frag[i].length()==frag[epos].length();i--){
if(used[i] || (res!=frag[spos]+frag[i] && res!=frag[i]+frag[spos])) continue; //frag[i]被占用或frag[i]不能与frag[spos]配对
//frag[i]能与frag[spos]配对,继续后续匹配
used[i] = true;
if(solve(spos+1,epos)) return true;
else{
used[i] = false; //虽然frag[i]能与frag[spos]匹配,但存在失败的后续匹配,也是不行
while(i>spos+1 && frag[i]==frag[i-1]) i--; //跳过与frag[i]相同的片段,避免重复搜索
}
}
used[spos] = false; //释放frag[spos]
return false; //没有一个满足条件的frag能与frag[spos]配对,表明当前的匹配方式是错误的
}
}
int main(){
//ifstream cin("input.txt");
int i;
while(getline(cin,frag[0])){
i=1;
while(getline(cin,frag[i])){
if(frag[i].size()==0) break;
else i++;
}
sort(frag,frag+i,Less()); //按按片段长度进行排序
len = frag[0].length() + frag[i-1].length(); //完整bit的长度
n = i;
solve(0,n-1);
cout<<res<<endl;
res = "";
for(int j=0;j<i;j++) used[j] = false;
}
return 0;
}