UVa10132

一个字符串(有多个副本)被切成了两段,要你找原字符串。

我的思想是既然都是原字符串切碎了,那么只要找到随便两个组合起来,这两个组合刚好是该字符串长度在验证其他串是由该串打碎的即可。

所以我们只要找到最长串,然后肯定是和最短串组合起来,一一验证即可,我们可以选定一个最长串或一个最短串,然后照他的另一半。

我的是选定一个最长串,从中找一个最短串和它匹配。匹配有两种方式,一种是最短在前最长在后,一种是最短在后,最长在前。然后一一验证。

副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;
}


你可能感兴趣的:(struct)