Description
输入m个长度均为n的DNF序列,求一个DNF序列,到所有的序列总Hamming距离尽量小。两个等长字符串的Hamming距离等于字符不同的位置个数,例如,ACGT和GCGA的Hamming距离为2,。
input
3
5 8
TATGATAC
TAAGCTAC
AAAGATCC
TGAGATAC
TAAGATGT
4 10
ACGTACGTAC
CCGTACGTAG
GCGTACGTAT
TCGTACGTAA
6 10
ATGTTACCAT
AAGTTACGAT
AACAAAGCAA
AAGTTACCTT
AAGTTACCAA
TACTTACCAA
output
TAAGATAC
7
ACGTACGTAA
6
AAGTTACCAA
12
思路分析:注意到题目要求是找出一个DNA序列,即重组一个DNF序列= =。我的想法就是按列搜索,先比较距离,如果距离相同再比较字典序。然后组合即可。附上代码,已经经过UVAOJ评测。
#include <iostream>
#include <string>
#include <string.h>
#include <ostream>
#include <fstream>
#include<cstdio>
#include<vector>
#define INFTY 2147483647
/*
5
5 8
TATGATAC
TAAGCTAC
AAAGATCC
TGAGATAC
TAAGATGT
4 10
ACGTACGTAC
CCGTACGTAG
GCGTACGTAT
TCGTACGTAA
6 10
ATGTTACCAT
AAGTTACGAT
AACAAAGCAA
AAGTTACCTT
AAGTTACCAA
TACTTACCAA
3 4
GATA
AGAT
CGTA
5 7
ATGTTAC
TTACCTT
TTACCAA
GTACGTA
AAGATCC
*/
using namespace std;
int m, n, T;
string s[50];
vector<char>minstr;
int label;
void search(int k)
{
int i, j, temp = 0, temp1 = INFTY; //temp记录当前字母的Hamming距离和,temp1记录截止到当前字母的所有搜索最小的距离
char tempc;//记录记录截止到当前字母的所有搜索最小距离的字母
//cout << "the present tagat is " <<endl<<endl;
for(i = 0; i < m; i++)
{
for(j = 0; j < m; j++)
{
if(s[i][k] != s[j][k])temp++;
}
//cout << "temp is " << temp <<endl;
if(temp1 > temp)
{
temp1 = temp;
tempc = s[i][k];
}
if(temp1 == temp)
{
if(s[i][k] < tempc)tempc = s[i][k];
}
//cout <<"tempc is " << tempc << endl;
// cout <<"temp1 is " << temp << endl;
temp = 0;
}
minstr.push_back(tempc);
// for(char p : minstr)
// cout << p;
// cout <<endl;
label = label + temp1;
}
int main()
{
// ofstream savefile("D:\\test.txt");
cin >> T;
while(T--)
{
cin >> m >> n;
//cout << "n is" << n <<endl;
getchar();
for(int i = 0; i < m; i++)
getline(cin, s[i]);
//cout << s[0] << endl;
// for(int i = 0; i < m; i++)
// cout << s[i] << endl;
// cout <<label <<endl;
for(int i = 0; i < n; i++)
{
search(i);
}
for(char p : minstr)
cout << p/*, savefile << p */;
cout <<endl;
// savefile << endl;
cout << label << endl;
// savefile << label << endl;
label = 0;
minstr.clear();
//minstr.clear();
}
// savefile.close();
}