Problem:
Problem C: Palindrome
Problem
太郎君はそれぞれの長さが
L
の文字列を
N
個持っている。太郎君は回文が大好きなので、
N
個のうちいくつかの文字列を選んで好きな順番に並べることで、できるだけ長い回文を作りたい。
太郎君が作ることのできる回文の中で、最長のものを求めよ。複数ある場合は、そのうち辞書順で最小のものを出力せよ。どのように選んで並べても回文が作れない場合は、空行を出力せよ。
Input
入力は以下の形式で与えられる。
N
L
s
1
s
2
.
.
.
s
N
1行目に、文字列の数
N
と文字列の長さ
L
が与えられる。続く2行目から
N
+ 1行目に太郎君が持っている文字列
s_i
が与えられる。
Constraints
入力は以下の条件を満たす。
1 ≤
N
≤ 1000
1 ≤
L
≤ 30
s_i
は英小文字からなる文字列である。
Output
最長の回文の中で辞書順最小のものを出力せよ。回文が作れない場合は空行を出力せよ。
Sample Input 1
4 2
oi
io
rr
rr
Sample Output 1
iorrrroi
Sample Input 2
5 1
a
b
c
a
c
Sample Output 2
acbca
Sample Input 3
3 3
uki
uku
uke
Sample Output 3
uku

Submitted solutions:

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
using namespace std;

typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 1000000007;
typedef double ld;
typedef complex<ld> Point;
const ll INF = mod * mod;
typedef pair<int, int> P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
typedef vector<int> vec;
typedef vector<string> svec;

vector<pair<string, string>> c;
void solve() {
	int n, l; cin >> n >> l;
	svec v(n);
	rep(i, n)cin >> v[i];
	vector<bool> used(n, false);
	rep(i, n) {
		if (used[i])continue;
		Rep(j,i+1, n) {
			if (used[j])continue;
			bool f = true;
			rep(k, l) {
				if (v[i][k] != v[j][l - k - 1])f = false;
			}
			if (f) {
				c.push_back({ v[i],v[j] });
				used[i] = used[j] = true;
				break;
			}
		}
	}
	string r;
	rep(i, n) {
		if (used[i])continue;
		bool f = true;
		rep(j, l) {
			if (v[i][j] != v[i][l - j - 1])f = false;
		}
		if (f) {
			if (r == "") {
				r = v[i];
			}
			else {
				r = min(r, v[i]);
			}
		}
	}
	rep(i, c.size()) {
		if (c[i].first > c[i].second)swap(c[i].first, c[i].second);
	}
	sort(c.begin(), c.end());
	string ans;
	rep(i, c.size()) {
		ans += c[i].first;
	}
	ans += r;
	per(i, (int)c.size()) {
		ans += c[i].second;
	}
	cout << ans << endl;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(5);
	//while (cin >> n>>h>>m>>s,n)solve();
	solve();
	//stop
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3304
final_rank: 6

code_snippet: #include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

int n,l;
vector<string> str;
vector<int> G[1001];
int aim[1001];
bool used[1001];


bool check(int a,int b){
	for(int i=0;i<l;i++){
		if(str[a][i]!=str[b][l-1-i])return false;
	}
	return true;
}

bool checkme(int a){
	for(int i=0;i<l/2;i++){
		if(str[a][i]!=str[a][l-1-i])return false;
	}
	return true;
}

int main(void){
	scanf("%d%d",&n,&l);
	for(int i=0;i<n;i++){
		string si;
		cin >> si;
		str.push_back(si);
	}
	sort(str.begin(),str.end());
	for(int i=0;i<n;i++){
		if(checkme(i))aim[i]=1;
		for(int j=i+1;j<n;j++){
			if(check(i,j)){
				G[i].push_back(j);
			}
		}
	}
	vector<string> resf;
	vector<string> rest;
	string resm="";
	for(int i=0;i<n;i++){
		if(used[i])continue;
		for(int j=0;j<G[i].size();j++){
			if(!used[G[i][j]]){
				used[i]=true;
				used[G[i][j]]=true;
				resf.push_back(str[i]);
				rest.push_back(str[G[i][j]]);
				break;
			}
		}
		if(!used[i] && aim[i]==1 && resm.size()==0){
			used[i]=true;
			resm+=str[i];
		}
	}
	string res="";
	for(int i=0;i<resf.size();i++){
		res+=resf[i];
	}
	res+=resm;
	for(int i=0;i<rest.size();i++){
		res+=rest[rest.size()-i-1];
	}
	cout << res << endl;
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3516
final_rank: 9

code_snippet: #include<bits/stdc++.h>

using namespace std;

int main()
{
  int N, L;
  string S[1000], T[1000];

  cin >> N >> L;
  for(int i = 0; i < N; i++) {
    cin >> S[i];
  }
  sort(S, S + N);
  for(int i = 0; i < N; i++) {
    T[i] = S[i];
    reverse(begin(T[i]), end(T[i]));
  }

  string ret;
  for(int i = 0; i <= N; i++) {
    multiset< string > exist;
    vector< string > curr;
    for(int j = 0; j < N; j++) {
      if(i == j) continue;
      if(exist.count(T[j])) {
        exist.erase(exist.find(T[j]));
        curr.emplace_back(T[j]);
      } else {
        exist.emplace(S[j]);
      }
    }
    sort(begin(curr), end(curr));
    string all = accumulate(begin(curr), end(curr), string());
    string rev = all;
    reverse(begin(rev), end(rev));
    string beet = all;
    if(T[i] == S[i]) beet += T[i];
    beet += rev;
    if(ret.size() < beet.size()) ret = beet;
    else if(ret.size() == beet.size()) ret = min(ret, beet);
  }

  cout << ret << endl;
}
accuracy: 1
time_ms: 260
memory_kb: 3412
final_rank: 10

code_snippet: #include<bits/stdc++.h>

using namespace std;

int main()
{
  int N, L;
  string S[1000], T[1000];

  cin >> N >> L;
  for(int i = 0; i < N; i++) {
    cin >> S[i];
    T[i] = S[i];
    reverse(begin(T[i]), end(T[i]));
  }

  string ret;
  for(int i = 0; i <= N; i++) {
    multiset< string > exist;
    vector< string > curr;
    for(int j = 0; j < N; j++) {
      if(i == j) continue;
      if(exist.count(T[j])) {
        exist.erase(exist.find(T[j]));
        curr.emplace_back(T[j]);
      } else {
        exist.emplace(S[j]);
      }
    }
    sort(begin(curr), end(curr));
    string all = accumulate(begin(curr), end(curr), string());
    string rev = all;
    reverse(begin(rev), end(rev));
    string beet = all;
    if(T[i] == S[i]) beet += T[i];
    beet += rev;
    if(ret.size() < beet.size()) ret = beet;
    else if(ret.size() == beet.size()) ret = min(ret, beet);
  }

  cout << ret << endl;
}
accuracy: 0.2857142857142857
time_ms: 280
memory_kb: 3444
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
/*{{{*/  //template
#define rep(i,n) for(int i=0;i<n;i++)
constexpr int INF = numeric_limits<int>::max()/2;
constexpr long long LINF = numeric_limits<long long>::max()/3;
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define all(v) (v).begin(),(v).end()
#define sz(x) (int)(x).size()
#define debug(x) cerr<<#x<<":"<<x<<endl
#define debug2(x,y) cerr<<#x<<","<<#y":"<<x<<","<<y<<endl
//struct fin{ fin(){ cin.tie(0); ios::sync_with_stdio(false); } } fin_;
struct Double{ double d; explicit Double(double x) : d(x){} };
ostream& operator<<(ostream& os,const Double x){ os << fixed << setprecision(20) << x.d; return os; }
template<typename T> ostream& operator<<(ostream& os,const vector<T>& vec){ os << "["; for(const auto& v : vec){ os << v << ","; } os << "]"; return os; }
template<typename T,typename U> ostream& operator<<(ostream& os,const pair<T,U>& p){ os << "(" << p.first << ","<< p.second <<")"; return os; }
template<typename T> ostream& operator<<(ostream& os,const set<T>& st){ os<<"{"; for(T v:st) os<<v<<","; os <<"}"; return os; }
template<typename T,typename U> inline void chmax(T &x,U y){ if(y>x) x = y; }
template<typename T,typename U> inline void chmin(T &x,U y){ if(y<x) x = y; }
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
ll gcd(ll a,ll b){ if(b==0) return a; else return gcd(b,a%b); }
//constexpr double eps = 1e-14; 
constexpr double eps = 1e-10; 
constexpr ll mod = 1e9+7;
const int dx[]={1,0,-1,0} ,dy[] = {0,1,0,-1};
/*}}}*/
int n;
int l;
array<string,1024> s;

bool ok(const string& st){
    auto ss = st;
    reverse(all(ss));
    return st == ss;
}

bool ok(string a, string b){
    reverse(all(b));
    return a == b;
}

vector<pair<string,string>> v;
array<bool,1024> used;

int main(){
    cin >> n;
    cin >> l;
    rep(i,n) cin >> s[i];
    rep(i,n) used[i] = false;

    for(int i=0;i<n;i++){
        for(int j=i+1;j<n;j++){
            if(ok(s[i],s[j]) and !used[i] and !used[j]){
                v.pb(mp(min(s[i],s[j]),max(s[i],s[j])));
                used[i] = used[j] = true;
            }
        }
    }

    sort(all(v));

    string ss = "";
    rep(i,n){
        if(!used[i] and ok(s[i])){
            if(ss=="") ss = s[i];
            else ss = min(ss,s[i]);
        }
    }

    string ans = ss;

    for(int i=v.size()-1;i>=0;i--){
        ans = v[i].fi + ans + v[i].se;
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 3244
final_rank: 2

code_snippet: #include<bits/stdc++.h>
#define rep(i,n) for(int i=0; i<n;i++)
using ll = long long;
#define all(in) in.begin(),in.end()
using namespace std;
int main(){
    int n; cin>>n;
    int f; cin>>f;
    vector<string>vs;
    rep(i,n){
        string t; cin>>t;
        vs.push_back(t);
    }
    vector<string>ans;
    vector<bool>used(n,true);
    rep(i,n)rep(j,n){
        if(i==j||used[j]==false||used[i]==false)continue;
        string temp=vs[j];
        reverse(all(temp));
        if(temp==vs[i]){
            used[i]=false; used[j]=false;
            if(vs[i]<vs[j])ans.push_back(vs[i]);
            else ans.push_back(vs[j]);
        }
    }
    string middle;
    rep(i,n){
        if(!used[i])continue;
        bool flag=true;
        for(ll z=0; z<vs[i].size()/2;z++)
            if(vs[i][z]!=vs[i][vs[i].size()-1-z])flag=false;
        if(flag){
            if(middle.size()==0)middle=vs[i];
            else if(middle.size()==vs[i].size()&&vs[i]<middle)middle=vs[i];
        }
    }
    string s;
    sort(all(ans));
    rep(i,ans.size())s+=ans[i];
    string l=s;
    reverse(all(l));
    cout<<s<<middle<<l<<endl;
}
accuracy: 1
time_ms: 40
memory_kb: 3284
final_rank: 7

code_snippet: #include<bits/stdc++.h>
#define rep(i,n) for(int i=0; i<n;i++)
using ll = long long;
#define all(in) in.begin(),in.end()
using namespace std;
int main(){
    int n; cin>>n;
    int f; cin>>f;
    vector<string>vs;
    rep(i,n){
        string t; cin>>t;
        vs.push_back(t);
    }
    vector<string>ans;
    vector<bool>used(n,true);
    rep(i,n)rep(j,n){
        if(i==j||used[j]==false||used[i]==false)continue;
        string temp=vs[j];
        reverse(all(temp));
        if(temp==vs[i]){
            used[i]=false; used[j]=false;
            if(vs[i]<temp)ans.push_back(vs[i]);
            else ans.push_back(temp);
        }
    }
    string middle;
    rep(i,n){
        if(!used[i])continue;
        bool flag=true;
        for(ll z=0; z<vs[i].size()/2;z++)
            if(vs[i][z]!=vs[i][vs[i].size()-1-z])flag=false;
        if(flag){
            if(middle.size()==0)middle=vs[i];
            else if(middle.size()==vs[i].size()&&vs[i]<middle)middle=vs[i];
        }
    }
    string s;
    sort(all(ans));
    rep(i,ans.size())s+=ans[i];
    string l=s;
    reverse(all(l));
    cout<<s<<middle<<l<<endl;
}
accuracy: 0.2857142857142857
time_ms: 40
memory_kb: 3236
final_rank: 11

code_snippet: #include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

vector<string> pa;
vector<string> lp;
vector<string> str;
#define pb push_back

bool comp(string a,string b)
{
  if(a.length()==b.length())
    return a<b;
  else
    return a.length()>b.length();
}

bool kaibun(string s)
{
  int i;
  int len=s.length();
  for(i=0;i<len/2;i++)
    if(s[i]!=s[len-i-1])
      return false;
  return true;
}

string rev(string s)
{
  reverse(s.begin(),s.end());
  return s;
}

int main()
{
  int n;
  int i;
  cin>>n>>i;
  string s,r;
  //  cin>>s;
  //cout<<kaibun(s)<<endl;

  for(i=0;i<n;i++)
    {
      cin>>s;/*
      r=rev(s);
      if(s>r)
	str.pb(r);
	else*/
      str.pb(s);
    }
  //  sort(str.begin(),str.end());
  //str.pb("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
  /*
  for(i=0;i<n;i++)
    {
      if(str[i]==str[i+1])
	{
	  pa.pb(str[i]);
	  i++;
	  continue;
	}
      else if(kaibun(str[i]))
	{
	  lp.pb(str[i]);
	  continue;
	}
    }
*/
  int j;
  for(i=0;i<n-1;i++)
    for(j=i+1;j<n;j++)
      {
	if(str[i]==rev(str[j]))
	  {
	    pa.pb(str[i]>str[j]?str[j]:str[i]);
	    str[i]=str[j]="zzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
	  }
      }
  for(i=0;i<n;i++)
    if(kaibun(str[i]))
      lp.pb(str[i]);
  //  printf("pa=%d,lp=%d\n",pa.size(),lp.size());
  if(pa.size()==0 && lp.size()==0)
    {
      puts("");
      return 0;
    }
  
  //  printf("aiu");
  sort(lp.begin(),lp.end(),comp);
  sort(pa.begin(),pa.end());

  string ans="";
  for(i=0;i<(int)pa.size();i++)
    ans+=pa[i];

  if(lp.size()!=0)
    cout<<ans<<lp[0]<<rev(ans)<<endl;
  else
    cout<<ans<<rev(ans)<<endl;
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3304
final_rank: 8

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>

using namespace std;

int main(){
    int n,l;
    cin >> n >> l;
    vector<string> in(n);
    for(int i=0;i<n;i++)cin >> in[i];

    string ans="";
    vector<int> frg(n);

    sort(in.begin(),in.end());
    for(int i=0;i<n;i++){
       if(frg[i]==1)continue;
        for(int j=i+1;j<n;j++){
            if(frg[j]==1)continue;

            string tmp=in[j];
            reverse(tmp.begin(),tmp.end());
            if(in[i]==tmp){
                ans+=in[i];
                frg[i]=frg[j]=1;
                break;
            }
        }
    }

    string a="";
    for(int i=0;i<n;i++){
        if(frg[i]==1)continue;
        string tmp=in[i];
        reverse(tmp.begin(),tmp.end());
        if(tmp==in[i]){
            a=in[i];
            break;
        }
    }
    string ansb = ans;
    reverse(ansb.begin(),ansb.end());

    ans += a;
    ans += ansb;
    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3268
final_rank: 3

code_snippet: // clang-format off
#include <bits/stdc++.h>
#define int long long
#define main signed main()
#define loop(i, a, n) for (int i = (a); i < (n); i++)
#define rep(i, n) loop(i, 0, n)
#define forever for (;;)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define prec(n) fixed << setprecision(n)
template<typename A> using V = std::vector<A>;
template<typename A> using F = std::function<A>;
template<typename A, typename B> using P = std::pair<A, B>;
using pii = P<int, int>;
using vi = V<int>;
using vd = V<double>;
using vs = V<std::string>;
using vpii = V<pii>;
using vvi = V<vi>;
using vvpii = V<vpii>;
constexpr int INF = sizeof(int) == sizeof(long long) ? 1000000000000000000LL : 1000000000;
constexpr int MOD = 1000000007;
constexpr double PI = 3.14159265358979;
template<typename A, typename B> bool cmin(A &a, const B &b) { return a > b ? (a = b, true) : false; }
template<typename A, typename B> bool cmax(A &a, const B &b) { return a < b ? (a = b, true) : false; }
constexpr bool odd(const int n) { return n & 1; }
constexpr bool even(const int n) { return ~n & 1; }
template<typename T> std::istream &operator>>(std::istream &is, std::vector<T> &v) { for (T &x : v) is >> x; return is; }
template<typename A, typename B> std::istream &operator>>(std::istream &is, std::pair<A, B> &p) { is >> p.first; is >> p.second; return is; }
using namespace std;
// clang-format on

template<typename String> bool isPalindrome(const String &s) {
  int n = s.size();
  rep(i, n / 2) if (s[i] != s[n - 1 - i]) return false;
  return true;
}

template<typename String> bool isPalindromeOf(String s, const String &t) {
  reverse(all(s));
  return s == t;
}

main {
  int n, l;
  cin >> n >> l;
  vs s(n);
  cin >> s;
  vi used(n);
  V<string> palis;
  rep(i, n) {
    if (used[i]) continue;
    loop(j, i + 1, n) {
      if (used[j]) continue;
      if (isPalindromeOf(s[i], s[j])) {
        used[i] = used[j] = true;
        string t = s[i];
        reverse(all(t));
        palis.emplace_back(min(t, s[i]));
        goto next;
      }
    }
  next:;
  }
  string midS = string(1, char('z' + 1));
  // int midSLen = 0;
  rep(i, n) {
    if (used[i]) continue;
    if (!isPalindrome(s[i])) continue;
    // if (midSLen == s[i].size()) cmin(midS, s[i]);
    // if (cmax(midSLen, s[i].size())) midS = s[i];
    cmin(midS, s[i]);
  }
  sort(all(palis));
  for (auto &t : palis) cout << t;
  if (midS != string(1, char('z' + 1))) cout << midS;
  reverse(all(palis));
  for (auto t : palis) {
    reverse(all(t));
    cout << t;
  }
  cout << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 3292
final_rank: 5

code_snippet: #include <iostream>
#include <algorithm>
#include <set>
#include <string>
#include <vector>

using namespace std;

int N, L;
vector<string>s;

int is_pali(string s1){
  for(int i=0;i<s1.size()/2;i++){
    if(s1[i] != s1[s1.size()-i-1]){
      return 0;
    }
  }
  return 1;
}

int is_reverse(string s1, string s2){
  reverse(s2.begin(), s2.end());
  return !s1.compare(s2);
}

int main()
{
  cin >> N >> L;
  for(int i=0;i<N;i++){
    string x;
    cin >> x;
    s.push_back(x);
  }
  sort(s.begin(), s.end());
  string resf = "";
  string resb = "";
  set<int>S;
  for(int i=0;i<s.size();i++){
    for(int j=i+1;j<s.size();j++){
      //      cout << s[i] << " " << s[j] << endl;
      if(is_reverse(s[i], s[j])){
	resf += s[i];
	resb =  s[j] + resb;
	S.insert(i);
	S.insert(j);
	s.erase(s.begin() + j);
	s.erase(s.begin() + i);
	i--;
	break;
      }
    }
  }
  string mid = "";
  for(int i=0;i<s.size();i++){
    if(is_pali(s[i])){
      mid = s[i];
      break;
    }
  }
  //  cout << S.size() << endl;
  cout << resf << mid << resb << endl;
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3228
final_rank: 1

code_snippet: #include "bits/stdc++.h"
using namespace std;
#ifdef _DEBUG
#include "dump.hpp"
#else
#define dump(...)
#endif

//#define int long long
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define all(c) begin(c),end(c)
const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)(1e9) + 7;
const double PI = acos(-1);
const double EPS = 1e-9;
template<class T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template<class T> bool chmin(T &a, const T &b) { if (a > b) { a = b; return true; } return false; }

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int N, L; cin >> N >> L;
	vector<string>v(N);
	rep(i, 0, N) {
		cin >> v[i];
	}
	vector<string>ans;
	vector<int>used(N, 0);
	rep(i, 0, N)rep(j, i + 1, N) {
		if (used[i] || used[j])continue;
		auto x = v[i];
		auto y = v[j];
		reverse(all(x));
		if (x == y) {
			if (v[i] < v[j])ans.push_back(v[i]);
			else ans.push_back(v[j]);
			used[i] = used[j] = 1;
		}

	}
	sort(all(ans));
	vector<string>center;
	rep(i, 0, N) {
		if (used[i])continue;
		auto x = v[i];
		reverse(all(x));
		if (v[i] == x) {
			center.push_back(v[i]);
		}
	}
	sort(all(center));
	string re;
	rep(i, 0, ans.size()) {
		re += ans[i];
	}
	if (center.size())re += center[0];
	rrep(i, 0, ans.size()) {
		auto x = ans[i];
		reverse(all(x));
		re += x;
	}
	cout << re << endl;
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3276
final_rank: 4