大致题意 : 给定n个01串, 串内串间可以随意互换, 求组成01回文串数量的最大值
分析 : 能组成01回文串的几种情况为:
偶数串 : 0偶1偶(0奇1奇则不能组成回文串)
奇数串: 0奇1偶 或 0偶1奇
因为可以随意互换, 对于总数为n的字符串, 可以计算01总数, 一个字符串一个字符串的去填01, 使得尽量满足回文串, 我们假设, 总数为这几种情况:
总数0偶1偶 :
1、若都是奇数串, 我们可以恰好拼出n个01回文(因为是偶数个奇数串才能使得总数0偶1偶, 此时可以组k个0奇1偶(0偶1奇)的情况, 使得总数为0偶1偶)
2.若都是偶数串, 可以拼k个偶数01回文
3.若是偶数奇数串都有, 可以先拼偶数串, 总数会依旧保持0偶1偶, 再去拼奇数串, 就和1的情况一样了
总数0奇1偶(0偶1奇) :
只可能都是奇数串, 且只有奇数个奇数串, 可以恰好拼出n个01回文
总数0奇1奇:
若都是偶数串, 则最多只能组n-1个01回文
若都是奇数串, 则不可能出现0奇1奇的情况
若偶奇都有, 则需至少有一个0奇1奇的情况, 即最多只能组n-1个01回文
综上: 只有当总数为0奇0偶, 且存在偶数串时, 能组n-1个回文串, 其他情况都能组出n个回文
ac代码如下:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
using namespace std;
const int N = 60;
char s[N];
int main()
{
int T;
scanf("%d", &T);
while(T -- )
{
int n;
cin>>n;
int a1 = 0, a0 = 0, f = 0; // f判断是否有偶串, a1,a0分别记录1,0总数
for(int i = 1; i<=n; i++)
{
cin>>s;
int len = strlen(s);
if(len & 1) f = 1;
for(int j = 0; s[j]; j++)
{
if(s[j] == '1') a1++;
else a0++;
}
}
if(!f && a0&1 && a1&1) n--;
cout<<n<<endl;
}
}