[map]answer

题面

题目描述

H H H 与小 Y Y Y 刚刚参加完 U O I P UOIP UOIP 外卡组的初赛,就迫不及待的跑出考场对答案。
“吔,我的答案和你都不一样!”,小 Y Y Y 说道,”我们去找神犇们问答案吧”。
外卡组试卷中共有 m m m 道判断题,小 H H H 与小 Y Y Y 一共从其他 n n n 个神犇那问了答案。之后又
从小 G G G 那里得知,这 n n n 个神犇中有 p p p 个考了满分, q q q 个考了零分,其他神犇不为满分或零分。
这可让小 Y Y Y 与小 H H H 犯了难。你能帮助他们还原出标准答案吗?如有多解则输出字典序最小
的那个。无解输出 − 1 -1 1

输入

第一行四个整数 n n n, m m m, p p p, q q q,意义如上描述。
接下来 n n n 行,每一行 m m m 个字符’ N N N’或’ Y Y Y’,表示这题这个神犇的答案。
输出
仅一行,一个长度为 m m m 的字符串或是 − 1 -1 1
样例输入

2 2 2 0
YY
YY

样例输出

YY

数据范围

30 % : n ≤ 100. 30\% : n \le 100. 30%:n100.
60 % : n ≤ 5000 , m ≤ 100. 60\% : n \le 5000 , m \le 100. 60%:n5000,m100.
100 % : 1 ≤ n ≤ 30000 , 1 ≤ m ≤ 500.   0 ≤ p , q 且 p + q ≤ n . 100\% : 1 \le n \le 30000 , 1 \le m \le 500.\ 0 \le p , q 且 p + q \le n. 100%:1n30000,1m500. 0p,qp+qn.

算法解析

map

C + + C++ C++ m a p map map提供的是一种键值对容器,里面的数据都是成对出现的,每一对中的第一个值称之为关键字 ( k e y ) (key) (key),每个关键字只能在 m a p map map中出现一次;第二个称之为该关键字的对应值。

这道题我们可以把每个人的答案当做一个字符串,用 m a p map map存起来;
map<string,int>m;
然后接着从最小的字典序开始枚举;

代码

#include<bits/stdc++.h>
#include<vector>
#include<map>
using namespace std;
int N,M,P,Q;
bool boo;
string s[200000],t;
map<string,int>m;
vector<string>ans;
void get(int a){
    char c;
    for(int i=0;i<=M-1;i++){
        c=getchar();
        while(c!='Y'&&c!='N'){c=getchar();}
        s[a][i]=c;
    }
}
void printPQ(){
    for(int j=0;j<=ans.size()-1;j++){
        for(int i=M-1;i>=0;i--){
            printf("%c",ans[j][i]);
        }
        printf("\n");   
    }
     
}
void PQ_0(string w){
    string t=w,s=w;
    bitset<10>x=0;
    int l=0,r=1,num;for(int i=1;i<M;i++)r=r*2+1;num=r;
    for(;l<=num;){
        x=l;for(int i=0;i<=M-1;i++)if(x[M-i-1]==0)s[i]='N',t[i]='Y';else s[i]='Y',t[i]='N';
        if(m[s]==0&&m[t]==0){
            for(int i=0;i<=M-1;i++){
                printf("%c",s[i]);
            }
            return ;
        }
        l++,r--;
    }
    printf("-1");
    return;
}
int main(){
    scanf("%lld%lld%lld%lld",&N,&M,&P,&Q);
    cin>>t;m[t]++;
    for(int i=1;i<=N;i++)s[i]=t;
    for(int i=2;i<=N;i++){get(i);m[s[i]]++;}
    sort(s+1,s+1+N);
    if(Q==0&&P==0){
        PQ_0(s[1]);
        return 0;
    }
    else {
        boo=1;
        for(int i=1;i<=N;i++){ 
            for(int j=0;j<M;j++){if(s[i][j]=='N')t[j]='Y';else t[j]='N';} 
            if(m[s[i]]==P&&m[t]==Q){
                cout<<s[i]<<endl;
                return 0;
            }
            if(m[s[i]]==Q&&m[t]==P){
                cout<<t<<endl;
                return 0;
            }
        }
        if(ans.empty())printf("-1");
        else printPQ();
        return 0;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值