题目意思: 有一个人有n个文件,每个文件都是相同的,现在这n个文件的每一个文件都被分成了两部分用字符序列表示,要我们找到原来文件的字符序列。
解题思路: 1:每一个文件都是分裂成两部分,每一种文件都是相同的,那么只要找到最小的长度和最大的长度,那么加起来就是文件的长度记为L。
2:知道了文件的长度,那么如果我们从第一个子串假设为S1开始,让它分别和后面的字串相匹配,匹配处理有两种可能AB和BA,如果长度为L,那么我们就把这两种情况全部放进map,那么我们可以知道S1基本上都可以和其中的一种匹配成正确的序列,那么只要枚举一遍这个所有子串,那么我们知道在map里面最多的序列就是正确的序列,因为基本上每一次都可以匹配出一个正确的序列
3:最后输出map中second最大的first即可
4:map使用简单介绍:如果我们要把s插入map,首先我们先判断s是否在map里面,用find函数查找,如果存在直接m[s]++,如果不存在那么我们就令m[s] = 1表示插入
5:输入的应用,因为是要读到EOF,所以用gets读入再转化为string,当ch[0] == '\0'时候break
代码:
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cctype>
#include <cctype>
#include <cmath>
#include <stack>
#include <list>
#include <map>
using namespace std;
#define MAXN 10010
int n , len;
string str[MAXN];
map<string , int>m;
void solve(){
int i , j , l , max;
int min_len , max_len;
string s , tmp_str[MAXN] , ans;
min_len = MAXN ; max_len = 0;
//找最小长度和最大长度
for(i = 0 ; i < len ; i++){
if(str[i].size() < min_len)
min_len = str[i].size();
if(str[i].size() > max_len)
max_len = str[i].size();
}
l = min_len+max_len;//文件长度
m.clear();
map<string , int>::iterator it;//迭代器
for(i = 0 ; i < len ; i++){
for(j = i+1 ; j < len ; j++){
s = str[i]+str[j];
if(s.size() > l)//注意一下这个地方,如果不加会RE,我也搞不懂
continue;
if(s.size() == l){
it = m.find(s);
if(it != m.end()) m[s]++;
else m[s] = 1;
}
s = str[j]+str[i];
if(s.size() == l){
it = m.find(s);
if(it != m.end()) m[s]++;
else m[s] = 1;
}
}
}
//找最大值
max = 0;
for(it = m.begin() ; it != m.end() ; it++){
if(max < it->second){
max = it->second;
ans = it->first;
}
}
cout<<ans<<endl;//输出
}
int main(){
//freopen("input.txt" , "r" , stdin);
char ch[500];
scanf("%d%*c%*c" , &n);
while(n--){
len = 0;
while(gets(ch)){
if(!ch[0]) break;
str[len] = "";
for(int j = 0 ; j < strlen(ch) ; j++)
str[len] += ch[j];
len++;
}
solve();
if(n) printf("\n");
}
return 0;
}