一个字符串(有多个副本)被切成了两段,要你找原字符串。
我的思想是既然都是原字符串切碎了,那么只要找到随便两个组合起来,这两个组合刚好是该字符串长度在验证其他串是由该串打碎的即可。
所以我们只要找到最长串,然后肯定是和最短串组合起来,一一验证即可,我们可以选定一个最长串或一个最短串,然后照他的另一半。
我的是选定一个最长串,从中找一个最短串和它匹配。匹配有两种方式,一种是最短在前最长在后,一种是最短在后,最长在前。然后一一验证。
副AC代码:注意最后一行数据不要输出空格,不然会WA的。搞了我N久。最后才发现。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string.h>
using namespace std;
const int Arsize=1000;
const int Maxlen=1000;
struct Node{
char str[Maxlen];
int len;
};
bool cmp(const Node &a,const Node &b){
return a.len<b.len;
}
int max_files;
Node fragments[Arsize];
int check(char *temp){
int i,flag,j,k,m;
flag=1;
for(i=0;i<max_files&&flag;i++){
flag=0;
for(j=0;temp[j];j++){
for(k=0,m=j;fragments[i].str[k]&&fragments[i].str[k]==temp[m];k++,m++)
;
if(k==fragments[i].len){
if(j==0||temp[m]=='\0')
flag=1;
}
}
}
if(flag)
return 1;
else
return 0;
}
int main()
{
int case_num,i,min_len,flag,j;
char temp1[Maxlen];
char temp2[Maxlen];
cin >> case_num;
cin.get();
cin.get();
while(case_num--){
i=0;
flag=0;
while(1){
cin.getline(temp1,Maxlen);
if(temp1[0]==0)
break;
fragments[i].len=strlen(temp1);
memcpy(fragments[i].str,temp1,sizeof(temp1));
i++;
}
max_files=i;
sort(fragments,fragments+max_files,cmp);
min_len=fragments[0].len;
memcpy(temp1,fragments[max_files-1].str,sizeof(temp1));
for(i=0;i<max_files&&!flag&&fragments[i].len==min_len;i++){
strcat(temp1,fragments[i].str);
j=check(temp1);
if(j){
flag=1;
break;
}
memcpy(temp2,fragments[i].str,sizeof(temp2));
strcat(temp2,fragments[max_files-1].str);
j=check(temp2);
if(j){
flag=2;
break;
}
}
if(flag==1){
cout << temp1 << endl;
}
else
cout << temp2 << endl;
if(case_num)
cout << endl;
}
return 0;
}