• 【考前模拟】正确答案


    1.正确答案

    【题目描述】

    小H与小Y刚刚参加完UOIP外卡组的初赛,就迫不及待的跑出考场对答案。

    “吔,我的答案和你都不一样!”,小Y说道,”我们去找神犇们问答案吧”。

    外卡组试卷中共有m道判断题,小H与小Y一共从其他n个神犇那问了答案。之后又从小G那里得知,这n个神犇中有p个考了满分,q个考了零分,其他神犇不为满分或零分。这可让小Y与小H犯了难。你能帮助他们还原出标准答案吗?如有多解则输出字典序最小的那个。无解输出-1。

    【输入格式】

    第一行四个整数n, m, p, q,意义如上描述。

    接下来n行,每一行m个字符’N’或’Y’,表示这题这个神犇的答案。

    【输出格式】

    仅一行,一个长度为m的字符串或是-1。

    【样例输入】

    2 2 2 0

    YY

    YY

    【样例输出】

    YY

    【数据范围】

    30% : n <= 100.

    60% : n <= 5000 , m <= 100.

    100% : 1 <= n <= 30000 , 1 <= m <= 500.  0 <= p , q 且 p + q <= n.

    T1:

    30%:  O(n ^ 2 * m)暴力判断。

    100%: 很显然答案的可能性最多只有n种,所以我们将所有人的答案按字典序排序后枚举     将每个人的答案作为正确答案来进行判断。由于是判断题,若当前人的答案为正确答      案则零分者的答案也就确定了,那么只需统计出这两种答案的人数判断是否满足题意      即可。这一步使用字符串哈希即可解决。

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    
    const int N = 3e4 + 2, M = 5e2 + 2, sed = 31, SED = 131, mod = 70177, MOD = 92311;
    int n, m, p, q, ans, hash[N], HASH[N];
    int top, info[mod], nxt[N * 2], fet[N * 2], cnt[N * 2];
    struct node {
        char s[M];
        inline bool operator < (const node &b) const {
            return strcmp(s, b.s) < 0;
        }
    } a[N];
    
    inline void Insert(const int &x, const int &y) {
        for (int k = info[x]; k; k = nxt[k])
            if (fet[k] == y) {
                ++cnt[k]; return ;
            }
        nxt[++top] = info[x]; info[x] = top;
        fet[top] = y; cnt[top] = 1;
        return ;
    }
    
    inline int Query(const int &x, const int &y) {
        for (int k = info[x]; k; k = nxt[k])
            if (fet[k] == y) return cnt[k];
        return 0;
    }
    
    inline void Solve1() {
        int tmp, TMP; ans = -1;
        for (int i = 0; i < n; ++i) {
            tmp = TMP = 0;
            for (int j = 0; j < m; ++j) {
                tmp = (tmp * sed + (a[i].s[j] == 'N')) % mod;
                TMP = (TMP * SED + (a[i].s[j] == 'N')) % MOD;
            }
            hash[i] = tmp, HASH[i] = TMP;
            Insert(tmp, TMP);
        }
        for (int i = 0; i < n; ++i)
            if (Query(hash[i], HASH[i]) == p) {
                tmp = TMP = 0;
                for (int j = 0; j < m; ++j) {
                    tmp = (tmp * sed + (a[i].s[j] == 'Y')) % mod;
                    TMP = (TMP * SED + (a[i].s[j] == 'Y')) % MOD;
                }
                if (Query(tmp, TMP) == q) {
                    ans = i; break;
                }
            }
        if (ans != -1) printf("%s
    ", a[ans].s);
        else     puts("-1");
        return ;
    }
    
    char cur[M];
    inline void Solve2() {
        int tmp, TMP; ans = -1;
        for (int i = 0; i < n; ++i) {
            tmp = TMP = 0;
            for (int j = 0; j < m; ++j) {
                tmp = (tmp * sed + (a[i].s[j] == 'N')) % mod;
                TMP = (TMP * SED + (a[i].s[j] == 'N')) % MOD;
            }
            hash[i] = tmp, HASH[i] = TMP;
            Insert(tmp, TMP);
        }
        for (int i = n - 1; i >= 0; --i)
            if (Query(hash[i], HASH[i]) == q) {
                tmp = TMP = 0;
                for (int j = 0; j < m; ++j) {
                    tmp = (tmp * sed + (a[i].s[j] == 'Y')) % mod;
                    TMP = (TMP * SED + (a[i].s[j] == 'Y')) % MOD;
                }
                if (Query(tmp, TMP) == p) {
                    ans = i; break;
                }
            }
        if (ans != -1) {
            for (int i = 0; i < m; ++i)
                cur[i] = a[ans].s[i] == 'N' ? 'Y' : 'N';
            printf("%s
    ", cur);
        }
        else     puts("-1");
        return ;
    }
    
    void Solve3() {
        int tmp, TMP;
        for (int i = 0; i < n; ++i) {
            tmp = TMP = 0;
            for (int j = 0; j < m; ++j) {
                tmp = (tmp * sed + (a[i].s[j] == 'N')) % mod;
                TMP = (TMP * SED + (a[i].s[j] == 'N')) % MOD;
            }
            Insert(tmp, TMP);
            tmp = TMP = 0;
            for (int j = 0; j < m; ++j) {
                tmp = (tmp * sed + (a[i].s[j] == 'Y')) % mod;
                TMP = (TMP * SED + (a[i].s[j] == 'Y')) % MOD;
            }
            Insert(tmp, TMP);
        }
        bool flag = true;
        for (int i = 0; i < m; ++i) cur[i] = 'N';
        do {
            tmp = TMP = 0;
            for (int j = 0; j < m; ++j) {
                tmp = (tmp * sed + (cur[j] == 'N')) % mod;
                TMP = (TMP * SED + (cur[j] == 'N')) % MOD;
            }
            if (Query(tmp, TMP) == 0) {
                flag = true; break;
            }
            flag = false;
            for (int j = m - 1; j >= 0; --j)
                if (cur[j] == 'Y') cur[j] = 'N';
                else {
                    cur[j] = 'Y'; flag = true; break;
                }
        } while (flag);
        if (flag) printf("%s
    ", cur);
        else     puts("-1");
        return ;
    }
    
    int main() {
        freopen("answer.in", "r", stdin);
        freopen("answer.out", "w", stdout);
        scanf("%d%d%d%d", &n, &m, &p, &q);
        for (int i = 0; i < n; ++i) scanf("%s", a[i].s);
        sort(a, a + n);
        if (p) Solve1();
        else if (q) Solve2();
        else     Solve3();
        fclose(stdin); fclose(stdout);
        return 0;
    }
    细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
  • 相关阅读:
    常用的清理 Kubernetes 集群命令
    mask彻底禁用systemctl服务
    ansibleplaybook指定role limit
    极速理解设计模式系列:16.迭代器模式(Iterator Pattern)
    极速理解设计模式系列:19.备忘录模式(Memento Pattern)
    极速理解设计模式系列:8.策略模式(Strategy Pattern)
    极速理解设计模式系列:6.适配器模式(Adapter Pattern)
    PostSharp AOP编程:2.PostSharp的OnMethodBoundaryAspect类基本组成
    极速理解设计模式系列:18.访问者模式(Visitor Pattern)
    极速理解设计模式系列:10.抽象工厂模式(Abstract Factory Pattern)
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/6061606.html
Copyright © 2020-2023  润新知