首页 > 其他分享 >NOIP2023

NOIP2023

时间:2023-11-20 21:25:21浏览次数:29  
标签:ok int rep mn NOIP2023 mx 字典

T1:词典

题意:

给定 \(n\) 个长度为 \(m\) 的字符串 \(w_1, w_2, \cdots, w_n\) 。
对于每个 \(i = 1, 2, \cdots, n\) 询问是否存在 \(w_1', w_2', \cdots, w_n'\) 使得对于每个 \(j = 1, 2, \cdots, n\),\(w_j'\) 都可以由 \(w_j\) 交换字符得到,且对于 \(j \neq i\) 都有 \(w_i'\) 的字典序小于 \(w_j'\) 。

数据范围:

\( 1 \leqslant n \leqslant 3000 \), \( 1 \leqslant m \leqslant 3000 \), 所有字符串均由小写字母构成

算法分析

做法1:

对于每个 \(i\), 如果存在方案的话必然可以让 \(w_i'\) 字典序最小,而其他的 \(j \neq i\) 的 \(w_j'\) 字典序最大。也就是让 \(w_i\) 的字符从小到大排序得到 \(w_i'\),让 \(w_j\) 的字符从大到小排序得到 \(w_j'\) 。

直接模拟这个过程的时间复杂度为 \(O(n^2m)\),期望得分 \(80\) 分。
但实际上可以拿 \(100\) 分。

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

int main() {
    freopen("dict.in", "r", stdin);
    freopen("dict.out", "w", stdout);
    
    int n, m;
    cin >> n >> m;
    
    vector<string> w(n);
    rep(i, n) cin >> w[i];
    
    vector<string> mn(n);
    rep(i, n) {
        mn[i] = w[i];
        sort(mn[i].begin(), mn[i].end());
    }
    vector<string> mx(n);
    rep(i, n) {
        mx[i] = w[i];
        sort(mx[i].rbegin(), mx[i].rend());
    }
    
    string ans;
    rep(i, n) {
        bool ok = true;
        rep(j, n) if (j != i) {
            if (mn[i] > mx[j]) {
                ok = false;
                break;
            }
        }
        ans += ok ? '1' : '0';
    }
    
    cout << ans << '\n';
    
    return 0;
}

做法2:

实际上我们发现没有必要模拟上述过程,因为得到的 \(w_i'\) 以及 \(w_j'\) 一定是一段一段的,最多 \(\sigma = 26\) 段,使用桶存下每个字符的出现次数,之后一段一段比较即可在 \(O(nm+\sigma n^2)\) 的复杂度内解决。期望得到 \(80 \sim 100\) 分。

做法3:

不妨再深入一步,设 \(f_i\) 表示 \(w_i\) 中出现的最小字母, \(g_i\) 表示 \(w_i\) 中出现的最大字母。
如果 \(f_i < g_i\),那么显然 \(w_i'\) 的字典序小于 \(w_j'\),只需要将 \(f_i\) 作为 \(w_i'\) 的第一个字母,\(g_j\) 作为 \(w_j'\) 的第一个字母即可。
如果 \(f_i > g_j\),那么显然 \(w_i'\) 的字典序大于 \(w_j'\)。
剩下最后一种情况 \(f_i = g_j\),想要 \(w_i'\) 的字典序最小,需要将 \(f_i\) 放在最前面,此时越往后 \(w_i'\) 的字母越大。想要 \(w_j'\) 的字典序最大,需要将 \(g_j\) 放在最前面,此时越往后 \(w_j'\) 的字母越小。因此此时必然有 \(w_i'\) 的字典序大于 \(w_j'\)。
综上,如果 \(i\) 可能,当且仅当 \(f_i < \min\limits_{j \neq i} g_j\)。因此可以 \(O(n)\) 完成这个过程,总的时间复杂度为 \(O(nm+n^2)\)。
期望得分:100分。

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

int main() {
    freopen("dict.in", "r", stdin);
    freopen("dict.out", "w", stdout);
    
    int n, m;
    cin >> n >> m;
    
    vector<int> f(n, 26), g(n, -1);
    rep(i, n) {
        string w;
        cin >> w;
        rep(j, m) {
            f[i] = min(f[i], w[j]-'a');
            g[i] = max(g[i], w[j]-'a');
        }
    }
    
    string ans;
    rep(i, n) {
        bool ok = true;
        rep(j, n) if (j != i) {
            if (f[i] >= g[j]) {
                ok = false;
                break;
            }
        }
        ans += ok ? '1' : '0';
    }
    
    cout << ans << '\n';
    
    return 0;
}

标签:ok,int,rep,mn,NOIP2023,mx,字典
From: https://www.cnblogs.com/Melville/p/17844826.html

相关文章

  • NOIP2023游记
    写下这篇游记的时候,我的内心是怎样的五味杂陈啊。随一首歌,随到了《如愿》。世间所有的路都将与你相逢。考前一天便感觉不太对劲,嗓子有点火辣辣地疼,鼻腔内也充斥着少量鼻涕。但这显然是心理作用的吧!于是第二天一上场头就开始变得有些蒙。偏偏系统炸了,大家都下不到题面。等......
  • noip2023 题解(民间数据)
    P9868[NOIP2023]词典(民间)直接把每个串\(w_i\)都从大到小/从小到大排一下,记作\(a_i,b_i\)。如果\(b_i\)小于除了\(i\)之外的所有\(a_i\),说明可以,否则不行。求一个前后缀最大值即可。复杂度\(\mathcal{O}(26n+nm)\)。点击查看代码#include<bits/stdc++.h>usingname......
  • CSP/NOIP2023 游记
    比赛的事情不想写了。可能就是不会考试吧,各种地方的失误,各种策略的失误,各种没来由的蠢。大概不知道我发生了什么的也看不懂我在乱抱怨什么。如果能力根本就不足以触碰到,如果区区肮脏的败者也想偷取星杯的话,那就不要以希望之名玩弄本就不存在的胜利啊。只可惜,生活终究不是动漫,里......
  • NOIP2023
    前情概括:csp爆炸,本次期望不高,目标是两题然后暴力打满。赛时情况:8:00到考场,吹了会水之后就进去了,有点点紧张。来到三楼的时候肚子就开始犯病。直接去厕所发现还要排队。/fn直接去四楼,因为没有手表心里慌的很,回来时已经8:27拿了个水杯就进场了,心砰砰跳。一遍过密码开题,开题顺序......
  • NOIP2023 游记
    Day-1最后一场模拟赛,死磕T1喜提\(15\)分,被Shui_Dream教育。正式比赛一定不能这么干啊,去年全国其他选手「喵了个喵」的惨痛经历令人发抖。想了很多种暴毙的情况,告诉自己一定不能犯。感觉后两题也不是很难啊。看来题目难度真不一定按顺序排列的啊。下午gj带我们去上了......
  • NOIP2023游记
    Day-??校庆期间润到机房看民间数据,发现CSPAK了一车,希望NOIP不要是这个难度!Day-?老叶和裘讲尽量给我们多一点时间,于是当天下午就开始停课了(Day-1请了个假回家睡大觉!早上被迫起来打集训队胡策,写写弄弄找了点规律花2h过了T3。发现T2是个巨大难写的仙人掌上长剖板......
  • NOIP2023 游记
    Day998244352(20231117)来到考点附近。在大巴车上玩poki,到站了玩MC,从中午玩到了晚上。Day0开题。T1一眼像是排序,但大约15min后意识到只要对每个字符串找到最大和最小然后\(O(n^2)\)就过了。T2每个点向最后的点连边,用并查集维护,如果\(x\)和\(\negx\)被连到......
  • NOIP2023游记
    省流:寄!Day-?开始全天停课,一天一场模拟赛。还是改不了死磕的毛病,经常纠结于一道题而舍弃了更好写的暴力。很好奇某位佬是怎么做到模拟赛划水还能天天rk1的。寄!Day-7全真模拟了luogu的模拟赛,然后成了rk1?要是noip也出构造就好了(虽然这不可能。拜谢rk2的coffee。......
  • noip2023游寄
    周五出发去广州,从周三晚上就回家了,然后一直写不进去题。好,周五了。好,坐动车去广州了。车上睡了很久,一会就到了。好,到广州了。坐了很久地铁,真的很累。找了好久旅馆,终于到了。好累,睡了好久。打了缩点的板子,睡了好久。18号了。好,打车去考场了。好,8:27了。好,开考了。t1会......
  • 游记 NOIP2023(public version)
    游记NOIP2023(publicversion)11.1720:30提前一天到达考点:中山市中山纪念中学。没有看鸭子。11.188:30正式开考。然后打开了一下虚拟机,有了上一次的经验,这次直接挂好了虚拟机的共享文件夹,题目也找到在哪里了,比较顺利。T1感觉比较简单,先做;T2......