因为这是个人的笔记所以记录一下自己解这题的过程
首先一心想暴力枚举求解却没有注意到会超时所以写了一份递归代码如下
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char k[10] = "AGCT";
char s[55][1005],s2[1005],s3[1005];
int ham,m,n;
void solve(int h)
{
if(h == 0)
{
int t = 0;
for(int k1 = 0; k1 < m; k1++) {
for(int k2 = 0; k2 < n; k2++) {
if(s[k1][k2] != s2[k2])
t++;
}
}
s2[n] = '\0';
if(t < ham)
{
ham = t;
strcpy(s3,s2);
}
else if(t == ham)
if(strcmp(s2,s3) < 0)
strcpy(s3,s2);
return;
}
for(int i = 0; i < 4; i++) {
s2[h-1] = k[i];
solve(h-1);
}
}
int main()
{
int T;
cin >> T;
while(T--) {
ham = 100000;
cin >> m >> n;
for(int k1 = 0; k1 < m; k1++)
for(int k2 = 0; k2 < n; k2++)
cin >> s[k1][k2];
solve(n);
printf("%s\n%d\n",s3,ham);
}
return 0;
}
嗯,结果提交自然收到超时的结果!=-=
于是重新设计了算法 。
先统计每列每个字符出现的次数,出现次数最多的那个字符就是我们要用来构造字符串的。
如果有多个字符出现的次数相同且都为最大,那么字典序ASCII码最小的字符就是要用来构造答案字符串的。
AC代码如下:
#include <iostream>
#include <cstdio>
#include <map>
using namespace std;
char s[55][1005], s2[1005];
int main()
{
map<char, int> cnt = { { 'A',0 },{ 'C',0 },{ 'G',0 },{ 'T',0 } };
int T, m,n;
cin >> T;
while (T--) {
int sum = 0;
cin >> m >> n;
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
cin >> s[i][j];
for (int j = 0; j < n; j++) {
cnt['A'] = 0,cnt['C'] = 0,cnt['G'] = 0,cnt['T'] = 0;
for (int i = 0; i < m; i++) { //统计j列每个字符出现的个数
cnt[s[i][j]]++;
}
int t = -1;
char c = 'Z';
for (auto iter = cnt.begin(); iter != cnt.end(); iter++)
{
if (t < iter->second)
{
t = iter->second;
c = iter->first;
}
else if (t == iter->second)
{
if (c > iter->first)
c = iter->first;
}
}
s2[j] = c;
sum += m-t;
}
s2[n] = '\0';
printf("%s\n%d\n", s2, sum);
}
return 0;
}