习题3-7 DNA Consensus String UVA - 1368

这个题我刚开始就想用容器来做,选了vector<map<char,int> >,相当于一个二维数组。每一个位置上的元素为一个map,map中就四种类型的元素,'A','T','C','G',对每一个位置对应的字母,这个map都+1,最后就成了统计每一个位置上四个字母的出现次数,找到出现次数最多的作为答案字符串上该位置的字符;如果出现次数一样多,就选字典序小的。

但是接下来思路乱了,我想的是排序找出第一个元素,但是后来发现为什么要排序,排map还是vector,我想不懂了,所以就没做下去。后来一想,向量每一个元素是一个map,那我只需要遍历每一个map,找到其中满足我们条件的就可以了。最后输出不同位置次数,只需要拿答案和原先的每一个字符串都比较一下,记一下数就行了。

但是,值得注意的是,我这两天被同一个错误卡了好几次,这就是变量作用域与是否需要初始化。我经常忘记每次把计数器、计数数组、标记数组初始化,或者初始化不当,导致最后答案错误。这种内部的逻辑错误很难发现,没办法,可能只能自己好好记住变量的含义,实在不行写几行汉语注释也可以啊。

#include <bits/stdc++.h>
using namespace std;
typedef map<char,int> mp;
typedef pair<char,int> pp;
vector<mp> v;
vector<string> st;
int main()  {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int m,n,w;
    cin>>w;
    while (w--) {
        string s;
        cin>>m>>n;
        for (int i=0;i<n;i++)   {
            mp mm;
            mm['A']=0;
            mm['T']=0;
            mm['C']=0;
            mm['G']=0;
            v.push_back(mm);
        }
        for (int i=0;i<m;i++)   {
            cin>>s;
            st.push_back(s);
            for (int j=0;j<n;j++)   {
                v[j][s[j]]++;
            }
        }
//        for (int i=0;i<n;i++)   {
//            mp::iterator it2=v[i].begin();
//            cout<<i<<endl;
//            for (;it2!=v[i].end();it2++)
//                cout<<(*it2).first<<' '<<(*it2).second<<' ';
//            cout<<endl;
//        }
        string ans="";
        //变量定义域没搞明白弄出的bug,两个这种bug
        int mx=-1;
        for (int i=0;i<n;i++)   {
            char c;
            mp::iterator it1=v[i].begin();
            for (;it1!=v[i].end();it1++)    {
                if ((*it1).second>mx)    {
                    mx=(*it1).second;
                    c=(*it1).first;
                }
                else if ((*it1).second==mx)
                    c=min(c,(*it1).first);
            }
            ans+=c;
            mx=-1;
        }
        int res=0;
        for (int i=0;i<(int)st.size();i++) {
            for (int j=0;j<(int)st[i].size();j++)
                if (st[i][j]!=ans[j])   res++;
        }
        cout<<ans<<'\n'<<res<<endl;
        v.clear();
        st.clear();
    }
    return 0;
}
posted @ 2018-09-14 13:24  CF过2100就买ARCTERYX  阅读(144)  评论(0编辑  收藏  举报