CF:#620場div2題目題解:B - Longest Palindrome

題目:

Returning back to problem solving, Gildong is now studying about palindromes. He learned that a palindrome is a string that is the same as its reverse. For example, strings “pop”, “noon”, “x”, and “kkkkkk” are palindromes, while strings “moon”, “tv”, and “abab” are not. An empty string is also a palindrome.

Gildong loves this concept so much, so he wants to play with it. He has n distinct strings of equal length m. He wants to discard some of the strings (possibly none or all) and reorder the remaining strings so that the concatenation becomes a palindrome. He also wants the palindrome to be as long as possible. Please help him find one.

Input
The first line contains two integers n and m (1≤n≤100, 1≤m≤50) — the number of strings and the length of each string.

Next n lines contain a string of length m each, consisting of lowercase Latin letters only. All strings are distinct.

Output
In the first line, print the length of the longest palindrome string you made.

In the second line, print that palindrome. If there are multiple answers, print any one of them. If the palindrome is empty, print an empty line or don’t print this line at all.

Examples

inputCopy
3 3
tab
one
bat
outputCopy
6
tabbat
inputCopy
4 2
oo
ox
xo
xx
outputCopy
6
oxxxxo
inputCopy
3 5
hello
codef
orces
outputCopy
0

inputCopy
9 4
abab
baba
abcd
bcde
cdef
defg
wxyz
zyxw
ijji
outputCopy
20
ababwxyzijjizyxwbaba
Note
In the first example, “battab” is also a valid answer.

In the second example, there can be 4 different valid answers including the sample output. We are not going to provide any hints for what the others are.

In the third example, the empty string is the only valid palindrome string.

題意

讀完題目我們知道,題目要求給出n個長度爲m的串串,讓你拼出一個最長迴文串,並且輸出長度和該回文串。

思路

首先就是這些序列長度都是m,這也就是說要麼是迴文串兩兩回文,中間有可能有個自己本身就是迴文串像是abba這樣的序列。

我們利用string類型的超方便函數就可以做了。

用map定義一個字符串數組之後就可以寫幾個函數,來檢查哪些自己就是一個迴文串:

bool check(int k)
{
	string str=all[k];
	for(int time=0;time<m/2;time++)
	{
		if(str[time]!=str[m-time-1])return false;
	}
	return true;
}

找到一個就夠了,外面這樣處理

for(int time=1;time<=n;time++)
	{
		if(check(time)){mid=time;ans+=m;break;}
	}

用mid記錄一下到底是哪個自己就是迴文串;
下一個函數就是檢查哪些是兩兩回文的,這就用到了我們的超方便函數:
reverse(str.begin(),str.end())來倒轉一個string類型變量。
str1.compare(str2)如果str1和str2是一樣的內容,比如aba和aba來compare一下,會返回0,否則就是一個非零的數,
我們就可以用if(!str1.compare(str2))表示倆變量是一回事。

bool FIND(int a,int b)
{
	reverse(all[b].begin(),all[b].end());
	if(!all[a].compare(all[b])){reverse(all[b].begin(),all[b].end());return true;}
		else	{reverse(all[b].begin(),all[b].end());return false;}
}
for(int time=1;time<=n;time++)
	{
		for(int time1=time+1;time1<=n;time1++)
		{
			if(FIND(time,time1)){left.push(time);right.push(time1);ans+=2*m;}
		}
	}

這樣就能很好解決問題,然後你們會發現上面代碼片的left和right是什麼,看一下前面

	queue<int>left;
	stack<int>right;

我用這倆容器就能決定輸出順序,畢竟你要按一定的順序輸出答案。
接下來就是輸出了,
上完整代碼:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <climits>
#include <queue>
#include <stack>
#include <map>
//鬼畜頭文件
using namespace std;
const int INF = 0x3f3f3f3f;
const int mod = 1e9+7;
typedef unsigned long long ULL;
typedef long long LL;
//鬼畜define

int n,m;
map<int ,string>all;
bool check(int k)
{
	string str=all[k];
	for(int time=0;time<m/2;time++)
	{
		if(str[time]!=str[m-time-1])return false;
	}
	return true;
}
bool FIND(int a,int b)
{
	reverse(all[b].begin(),all[b].end());
	if(!all[a].compare(all[b])){reverse(all[b].begin(),all[b].end());return true;}
		else	{reverse(all[b].begin(),all[b].end());return false;}
}
int main()
{
	scanf("%d %d",&n,&m);
	for(int time=1;time<=n;time++)
	{
		cin>>all[time];
	}
	int ans=0;
	int mid=0;
	for(int time=1;time<=n;time++)
	{
		if(check(time)){mid=time;ans+=m;break;}
	}
	queue<int>left;
	stack<int>right;
	for(int time=1;time<=n;time++)
	{
		for(int time1=time+1;time1<=n;time1++)
		{
			if(FIND(time,time1)){left.push(time);right.push(time1);ans+=2*m;}
		}
	}
	printf("%d\n",ans);
	while(!left.empty())
	{
		cout<<all[left.front()];
		left.pop();
	}
	if(mid)cout<<all[mid];
	while(!right.empty())
	{
		cout<<all[right.top()];
		right.pop();
	}
	printf("\n");
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章