天天看點

PAT乙級-1073 多選題常見計分法 (20 分)

題目連結

解題思路參考柳婼

#include<iostream>
#include<vector>
using namespace std;

int main(){
    int n,m;
    cin>>n>>m;
    int hash[5]={1,2,4,8,16}; //選項個數不超過5個
    vector<int> fullscore(m),trueopthash(m);
    int optnum,trueoptnum;
    char opt;
    for(int i=0;i<m;i++){
        cin>>fullscore[i]>>optnum>>trueoptnum;
        for(int j=0;j<trueoptnum;j++){
            scanf(" %c",&opt);
            trueopthash[i]+=hash[opt-'a']; //根據二進制位1所在的位置判斷選擇了哪些選項
        }
    }
    vector<vector<int>> cnt(m,vector<int>(5));
    for(int i=0;i<n;i++){
        double score=0.0;
        for(int j=0;j<m;j++){
            int selnum,selopthash=0;
            getchar(); //吃掉回車
            scanf("(%d",&selnum);
            for(int k=0;k<selnum;k++){
                scanf(" %c",&opt);
                selopthash+=hash[opt-'a'];
            }
            scanf(")");
            int el=selopthash^trueopthash[j];//^二進制異或運算,二進制位相同對應位結果為0,不同對應位結果為1
            if(!el) score+=fullscore[j]; //選項全正确
            else{
                if((selopthash|trueopthash[j])==trueopthash[j]) //選項部分正确,注意加括号(selopthash|trueopthash[j])
                    score+=fullscore[j]*1.0/2; //|二進制或運算,隻要二進制位有一個為1,則對應位結果為1
                for(int k=0;k<5;k++) //找出錯誤選項号
                    if(el&hash[k]) cnt[j][k]++; //&二進制與運算,二進制位都為1,對應位結果才為1
            }
        }
        printf("%.1f\n",score);
    }
    int maxcnt=0;
    for(int i=0;i<m;i++)
        for(int j=0;j<5;j++)
            if(cnt[i][j]>maxcnt) maxcnt=cnt[i][j];
    if(maxcnt==0) cout<<"Too simple"<<endl;
    else{
        for(int i=0;i<m;i++)
            for(int j=0;j<5;j++)
                if(cnt[i][j]==maxcnt) printf("%d %d-%c\n",maxcnt,i+1,j+'a');
    }
    return 0;
}
           

知識:位運算符的使用

繼續閱讀