一个字符串(有多个副本)被切成了两段,要你找原字符串。
我的思想是既然都是原字符串切碎了,那么只要找到随便两个组合起来,这两个组合刚好是该字符串长度在验证其他串是由该串打碎的即可。
所以我们只要找到最长串,然后肯定是和最短串组合起来,一一验证即可,我们可以选定一个最长串或一个最短串,然后照他的另一半。
我的是选定一个最长串,从中找一个最短串和它匹配。匹配有两种方式,一种是最短在前最长在后,一种是最短在后,最长在前。然后一一验证。
副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; }