前言

  • 这是我第一次写7题(A~G)的ABC题解,若有写得不好或者不到位的地方请多多指教,我将万分感激,感谢大家的支持!

ABC252 A~G

  • [A - ASCII code](https://atcoder.jp/contests/abc252/tasks/abc252_a)
    • 题目大意
    • 输入格式
    • 输出格式
    • 分析
    • 代码
  • [B - Takahashi's Failure](https://atcoder.jp/contests/abc252/tasks/abc252_b)
    • 题目大意
    • 输入格式
    • 输出格式
    • 分析
    • 代码
  • [C - Slot Strategy](https://atcoder.jp/contests/abc252/tasks/abc252_c)
    • 题目大意
    • 输入格式
    • 输出格式
    • 分析
    • 代码
  • [D - Distinct Trio](https://atcoder.jp/contests/abc252/tasks/abc252_d)
    • 题目大意
    • 输入格式
    • 输出格式
    • 分析
    • 代码
  • [E - Road Reduction](https://atcoder.jp/contests/abc252/tasks/abc252_e)
    • 题目大意
    • 输入格式
    • 输出格式
    • 分析
    • 代码
  • [F - Bread](https://atcoder.jp/contests/abc252/tasks/abc252_f)
    • 题目大意
    • 输入格式
    • 输出格式
    • 分析
    • 代码
  • [G - Pre-Order](https://atcoder.jp/contests/abc252/tasks/abc252_g)
    • 题目大意
    • 输入格式
    • 输出格式
    • 分析
    • 代码

A - ASCII code

题目大意

给定正整数NNN,输出ASCII码是NNN的字母。
97≤N≤12297\le N\le 12297≤N≤122

输入格式

NNN

输出格式

输出ASCII码是NNN的字母。

分析

注意a对应979797,b对应989898,……,z对应122122122。
安上小白专属转换教程:

  • C

    int n = 97;
    putchar(n); /* 输出:a */
    

    putchar函数自动转换为字符,也可以使用printf("%c", n)效果相同

  • C++
    int n = 97;
    cout << char(n) << endl; // 输出:a
    

    直接cout << n会输出97,需要用char转换为字符

  • Python
    n = 97
    print(chr(n)) # 输出:a
    

    同样也不能直接输出,需要用chr转换

  • Java
    int n = 97;
    char c = (char) n;
    System.out.print(c);
    

    与C++、Python类似,需要转换

  • JavaScript
    var n = 97;
    var c = String.fromCharCode(n);
    console.log(c); // 输出:a
    

    同样使用接口转化,需调用String.fromCharCode

再不懂你试试……

代码

太水,直接走一发py(现场25秒AC)

print(chr(int(input())))

B - Takahashi’s Failure

题目大意

Takahashi的房子里有NNN个食物。第iii个食物的美味度是AiA_iAi​。
其中,他不喜欢KKK个食物:B1,B2,…,BKB_1,B_2,\dots,B_KB1​,B2​,…,BK​。
已知Takahashi会从NNN个食物中随机选取一个美味度最大的食物,并把它吃掉。
Takahashi是否有可能迟到不喜欢的食物?

1≤K≤N≤1001\le K\le N\le 1001≤K≤N≤100
1≤Ai≤1001\le A_i\le 1001≤Ai​≤100
1≤Bi≤N1\le B_i\le N1≤Bi​≤N

输入格式

NKN~KN K
A1…ANA_1~\dots~A_NA1​ … AN​
B1…BKB_1~\dots~B_KB1​ … BK​

输出格式

如果有可能,输出Yes;否则,输出No

分析

只要有不喜欢的食物美味度最高就有可能,否则不可能。详见代码。

代码

还是水,注意如果是0-indexed\text{0-indexed}0-indexed的话BiB_iBi​要减111

#include <cstdio>
using namespace std;int a[105];int main()
{int n, k, mx = 0;scanf("%d%d", &n, &k);for(int i=0; i<n; i++){scanf("%d", a + i);if(a[i] > mx) mx = a[i];}while(k--){scanf("%d", &n);if(a[--n] == mx){puts("Yes");return 0;}}puts("No");return 0;
}

C - Slot Strategy

题目大意

略,请自行前往AtCoder查看。

2≤N≤1002\le N\le 1002≤N≤100

输入格式

NNN
S1S_1S1​
⋮\vdots⋮
SNS_NSN​

输出格式

输出答案。

分析

令cnt[i][j]=(Sk[j]=i\text{cnt}[i][j]=(S_k[j]=icnt[i][j]=(Sk​[j]=i的个数))),对最终变成000-999分别计算代价即可。详见代码。

代码

#include <cstdio>
using namespace std;int cnt[10][10]; // cnt[i][j] = number of (s[j]=i)int main()
{int n;scanf("%d", &n);for(int i=0; i<n; i++){char s[15];scanf("%s", s);for(int j=0; j<10; j++)cnt[s[j] ^ 48][j] ++;}int ans = 1000;for(int i=0; i<10; i++){int cur = 0;for(int j=0; j<10; j++){int c = j + (cnt[i][j] - 1) * 10;if(c > cur) cur = c;}if(cur < ans) ans = cur;}printf("%d\n", ans);return 0;
}

D - Distinct Trio

题目大意

给定长为NNN的整数序列A=(A1,…,AN)A=(A_1,\dots,A_N)A=(A1​,…,AN​)。
求符合以下条件的整数对(i,j,k)(i,j,k)(i,j,k)的个数:

  • 1≤i<j<k≤N1\le i<j<k\le N1≤i<j<k≤N
  • Ai≠Aj≠AkA_i\ne A_j\ne A_kAi​=Aj​=Ak​

3≤N≤2×1053\le N\le 2\times 10^53≤N≤2×105
1≤Ai≤2×1051\le A_i\le 2\times 10^51≤Ai​≤2×105

输入格式

NNN
A1…ANA_1~\dots~A_NA1​ … AN​

输出格式

输出一行,即符合条件的整数对(i,j,k)(i,j,k)(i,j,k)的个数。

分析

本题主要有两种思路:

  1. 逆向思维,用总数-不符合条件的;
  2. 将题目转化为求Ai<Aj<AkA_i<A_j<A_kAi​<Aj​<Ak​的(i,j,k)(i,j,k)(i,j,k)的个数。

这里介绍第一种方法(第二种方法较为简单,不详细说明)。

首先易得,总共的1≤i<j<k≤N1\le i<j<k\le N1≤i<j<k≤N有Cn3C_n^3Cn3​种取法。
然后考虑Ai,Aj,AkA_i,A_j,A_kAi​,Aj​,Ak​中有重复的个数:

  • 对于AAA中每个数xxx,我们记录cntx=A\text{cnt}_x=Acntx​=A中xxx出现的次数;
  • 然后,如果cntx≥2\text{cnt}_x\ge 2cntx​≥2,则将答案减去Ccntx2×(N−cntx)C_{\text{cnt}_x}^2\times(N-\text{cnt}_x)Ccntx​2​×(N−cntx​),即x,x,yx,x,yx,x,y格式出现的次数;
  • 又如果cntx≥3\text{cnt}_x\ge 3cntx​≥3,将答案减去Ccntx3C_{\text{cnt}_x}^3Ccntx​3​,即x,x,xx,x,xx,x,x的次数。

总时间复杂度为O(N+max⁡A−min⁡A)\mathcal O(N+\max_A-\min_A)O(N+maxA​−minA​),空间复杂度为O(max⁡A−min⁡A)\mathcal O(\max_A-\min_A)O(maxA​−minA​)。

代码

#include <cstdio>
#define maxn 200005
using namespace std;using LL = long long;
int cnt[maxn];inline LL C2(int n) { return n * (n - 1LL) >> 1LL; }
inline LL C3(int n) { return C2(n) * (n - 2LL) / 3LL; }int main()
{int n;scanf("%d", &n);for(int i=0; i<n; i++){int a;scanf("%d", &a);cnt[a] ++;}LL ans = C3(n);for(int i=1; i<maxn; i++)if(cnt[i] > 1){ans -= C2(cnt[i]) * (n - cnt[i]);if(cnt[i] > 2) ans -= C3(cnt[i]);}printf("%lld\n", ans);return 0;
}

E - Road Reduction

题目大意

给定一张由NNN个点和MMM条边组成的简单无向图。
第iii条边长度为CiC_iCi​,同时连接点AiA_iAi​和BiB_iBi​。
求任意一颗生成树,使得从点111到其他所有点的距离之和最小。

2≤N≤2×1052\le N\le 2\times 10^52≤N≤2×105
N−1≤M≤2×105N-1\le M\le 2\times 10^5N−1≤M≤2×105
1≤Ai<Bi≤N1\le A_i<B_i\le N1≤Ai​<Bi​≤N
(Ai,Bi)≠(Aj,Bj)(A_i,B_i)\ne(A_j,B_j)(Ai​,Bi​)=(Aj​,Bj​)(i≠ji\ne ji=j)
1≤Ci≤1091\le C_i\le 10^91≤Ci​≤109

输入格式

NMN~MN M
A1B1C1A_1~B_1~C_1A1​ B1​ C1​
⋮\vdots⋮
AMBMCMA_M~B_M~C_MAM​ BM​ CM​

输出格式

按任意顺序输出留下来的N−1N-1N−1条边的下标,用空格隔开。

分析

显然,在生成树中,点111到任意点的距离肯定不少于在原图中到这个点的距离。
因此,如果两个距离相等,显然就是最优解。
此时可以证明,肯定有这样的解。使用Dijkstra算法求最短路径的同时,记录到每个点之前的最后一条路即可。

代码

Dijkstra的两种经典实现方式,O(Nlog⁡N+Mlog⁡N)\mathcal O(N\log N+M\log N)O(NlogN+MlogN)

  • priority_queue优先队列(182ms182\text{ms}182ms)

    #include <cstdio>
    #include <queue>
    #define maxn 200005
    #define INF 9223372036854775807LL
    using namespace std;using LL = long long;
    using pli = pair<LL, int>;struct Edge
    {int v, id; LL d;inline Edge(int u, int l, int i): v(u), d(l), id(i) {}
    };vector<Edge> G[maxn];
    LL dis[maxn];
    int ans[maxn];int main()
    {int n, m;scanf("%d%d", &n, &m);for(int i=1; i<=m; i++){int a, b, c;scanf("%d%d%d", &a, &b, &c);G[--a].emplace_back(--b, c, i);G[b].emplace_back(a, c, i);}priority_queue<pli, vector<pli>, greater<pli>> q;for(int i=1; i<n; i++) dis[i] = INF;q.emplace(0LL, 0);while(!q.empty()){auto [d, v] = q.top(); q.pop();if(dis[v] == d)for(const Edge& e: G[v]){LL nd = d + e.d;if(nd < dis[e.v])q.emplace(dis[e.v] = nd, e.v),ans[e.v] = e.id;}}for(int i=1; i<n; i++) printf("%d ", ans[i]);return 0;
    }
    
  • set集合(202ms202\text{ms}202ms)
    #include <cstdio>
    #include <vector>
    #include <set>
    #define maxn 200005
    #define INF 9223372036854775807LL
    using namespace std;using LL = long long;
    using pli = pair<LL, int>;struct Edge
    {int v, id; LL d;inline Edge(int u, int l, int i): v(u), d(l), id(i) {}
    };vector<Edge> G[maxn];
    LL dis[maxn];
    int ans[maxn];int main()
    {int n, m;scanf("%d%d", &n, &m);for(int i=1; i<=m; i++){int a, b, c;scanf("%d%d%d", &a, &b, &c);G[--a].emplace_back(--b, c, i);G[b].emplace_back(a, c, i);}set<pli> s; // <distance, vertex>for(int i=1; i<n; i++) dis[i] = INF;s.emplace(0LL, 0);while(!s.empty()){auto [d, v] = *s.begin(); s.erase(s.begin());for(const Edge& e: G[v]){LL nd = d + e.d;if(nd < dis[e.v]){if(dis[e.v] < INF)s.erase(pli(dis[e.v], e.v));s.emplace(dis[e.v] = nd, e.v);ans[e.v] = e.id;}}}for(int i=1; i<n; i++) printf("%d ", ans[i]);return 0;
    }
    

注意使用long long


F - Bread

题目大意

本题翻译已经过简化,部分表示与原题不同,仅供参考,请以原题为准

有一个的整数序列SSS,初始只有一个元素LLL,我们可以执行如下操作无限次:

  • 从SSS中删去任意元素kkk(k>1k>1k>1),同时选取整数xxx(1≤x≤k−11\le x\le k-11≤x≤k−1),将xxx和k−xk-xk−x放入SSS。此操作的代价为kkk。

求最小的代价,使得AAA在SSS中,即AAA中每个元素的出现次数≤S~\le S ≤S中对应元素的出现次数

2≤N≤2×1052\le N\le 2\times 10^52≤N≤2×105
1≤N≤1091\le N\le 10^91≤N≤109
A1+A2+⋯+AN≤L≤1015A_1+A_2+\dots+A_N\le L\le 10^{15}A1​+A2​+⋯+AN​≤L≤1015

输入格式

NLN~LN L
A1…ANA_1~\dots~A_NA1​ … AN​

输出格式

输出最小的代价。

分析

本题考虑逆向思维,仔细思考后发现题目可以如下转化:

  • 令S=(A1,…,AN,L−∑A)S=(A_1,\dots,A_N,L-\sum A)S=(A1​,…,AN​,L−∑A)(L=∑AL=\sum AL=∑A时不千万不要加上最后一个元素)
  • 每次操作将AAA中任意两个元素合并,它们的和即为合并后新的元素,也是本次操作的代价
  • 最后发现全部合并完后SSS中正好剩下一个LLL,此时操作结束,所有代价和即为方案的最终代价。

此时,显然每次合并最小的两个数即为最优方案,因此可以使用优先队列实现,总时间复杂度为O(Nlog⁡N)\mathcal O(N\log N)O(NlogN)。

代码

注意使用long long

#include <cstdio>
#include <queue>
using namespace std;using LL = long long;int main()
{int n;LL l;scanf("%d%lld", &n, &l);priority_queue<LL, vector<LL>, greater<LL>> q;for(int i=0; i<n; i++){int x;scanf("%d", &x);q.push(x);l -= x;}if(l > 0) q.push(l);LL ans = 0LL;while(q.size() > 1){LL x = q.top(); q.pop();x += q.top(); q.pop();ans += x;q.push(x);}printf("%lld\n", ans);return 0;
}

G - Pre-Order

题目大意

有一颗由NNN个节点1,2,…,N1,2,\dots,N1,2,…,N组成的树,它的根节点为111。
它的先序遍历序列是(P1,P2,…,PN)(P_1,P_2,\dots,P_N)(P1​,P2​,…,PN​)。
每次搜索时,我们都会优先前往编号小的节点
有多少种不同的树,使其符合上述条件?对998244353998244353998244353取模。

2≤N≤5002\le N\le 5002≤N≤500
1≤Pi≤N1\le P_i\le N1≤Pi​≤N
P1=1P_1=1P1​=1
P1≠P2≠…≠PNP_1\ne P_2\ne\dots\ne P_NP1​=P2​=…=PN​

输入格式

NNN
P1…PNP_1~\dots~P_NP1​ … PN​

输出格式

输出答案,对998244353998244353998244353取模。

分析

我们先将PPP变为0-indexed\text{0-indexed}0-indexed,即原来的(P1,P2,…,PN)(P_1,P_2,\dots,P_N)(P1​,P2​,…,PN​)分别对应(A0,A1,…,AN−1)(A_0,A_1,\dots,A_{N-1})(A0​,A1​,…,AN−1​)。
此时,不妨考虑区间dp\text{dp}dp的思想,设dp(l,r)=(\mathrm{dp}(l,r)=~(dp(l,r)= (一棵树已经去掉根节点的先序遍历为Al,Al+1,…,Ar−1A_l,A_{l+1},\dots,A_{r-1}Al​,Al+1​,…,Ar−1​的可能数))),则dp(1,N)\mathrm{dp}(1,N)dp(1,N)即为所求。

下面考虑dp(l,r)\mathrm{dp}(l,r)dp(l,r)的动态转移方程。

  • 先考虑AlA_lAl​为Al+1,…,Ar−1A_{l+1},\dots,A_{r-1}Al+1​,…,Ar−1​的祖宗的情况,如图:

    易得,此时dp(l,r)\mathrm{dp}(l,r)dp(l,r)初始化为dp(l+1,r)\mathrm{dp}(l+1,r)dp(l+1,r)。
  • 再考虑区分左右子树,对于每个kkk(l<k<rl<k<rl<k<r),将Al,…,Ak−1A_l,\dots,A_{k-1}Al​,…,Ak−1​当作左子树(可能数为dp(l+1,k)\mathrm{dp}(l+1,k)dp(l+1,k)),再将Ak,…,Ar−1A_k,\dots,A_{r-1}Ak​,…,Ar−1​当作右子树(可能数为dp(k,r)\mathrm{dp}(k,r)dp(k,r)),此时如果Al<AkA_l<A_kAl​<Ak​则符合题意,将dp(l,r)\mathrm{dp}(l,r)dp(l,r)加上dp(l+1,k)×dp(k,r)\mathrm{dp}(l+1,k)\times \mathrm{dp}(k,r)dp(l+1,k)×dp(k,r)即可。

至此,本题已结束,时间复杂度为O(N3)\mathcal O(N^3)O(N3)。

代码

注意事项:

  1. 乘法操作需要转为long long再取模。
  2. 答案为dp(1,N)\mathrm{dp}(1,N)dp(1,N),不是dp(0,N)\mathrm{dp}(0,N)dp(0,N)。
  3. 注意区间dp\text{dp}dp计算顺序,参考代码提供两种写法(先枚举lll和先枚举长度)。
  • 写法一(先枚举lll,59ms59\text{ms}59ms)

    #include <cstdio>
    #define MOD 998244353
    #define maxn 505
    using namespace std;using LL = long long;
    int p[maxn], dp[maxn][maxn];int main()
    {int n;scanf("%d", &n);for(int i=0; i<n; i++)scanf("%d", p + i);for(int l=n; l>0; l--){dp[l][l] = 1;for(int r=l+1; r<=n; r++){dp[l][r] = dp[l + 1][r];for(int k=l+1; k<r; k++)if(p[l] < p[k] && (dp[l][r] += LL(dp[l + 1][k]) * dp[k][r] % MOD) >= MOD)dp[l][r] -= MOD;}}printf("%d\n", dp[1][n]);return 0;
    }
    
  • 写法二(先枚举长度,66ms66\text{ms}66ms)
    #include <cstdio>
    #define MOD 998244353
    #define maxn 505
    using namespace std;using LL = long long;
    int p[maxn], dp[maxn][maxn];int main()
    {int n;scanf("%d", &n);for(int i=0; i<n; i++)scanf("%d", p + i);for(int i=1; i<=n; i++)dp[i][i] = 1;for(int d=1; d<=n; d++)for(int l=1, r=d+1; r<=n; l++, r++){dp[l][r] = dp[l + 1][r];for(int k=l+1; k<r; k++)if(p[l] < p[k] && (dp[l][r] += LL(dp[l + 1][k]) * dp[k][r] % MOD) >= MOD)dp[l][r] -= MOD;}printf("%d\n", dp[1][n]);return 0;
    }
    

AtCoder Beginner Contest 252 A~G 题解相关推荐

  1. AtCoder Beginner Contest 246 A~E 题解 Bishop 2

    AtCoder Beginner Contest 246 A~E 题解 A Four Points 题意 给你矩形的三个顶点,输出剩下那个 思路 把横坐标和纵坐标分开,必会存在两个相同的数,横纵坐标就 ...

  2. AtCoder Beginner Contest 242 C~E 题解

    ABC242 C~E [C - 1111gal password](https://atcoder.jp/contests/abc242/tasks/abc242_c) 题目大意 输入格式 输出格式 ...

  3. AtCoder Beginner Contest 254 A~E 题解

    ABC254 A~E [A - Last Two Digits](https://atcoder.jp/contests/abc254/tasks/abc254_a) 题目大意 输入格式 输出格式 样 ...

  4. AtCoder Beginner Contest 204 A~E 题解

    ABC204 A~E [A - Rock-paper-scissors](https://atcoder.jp/contests/abc204/tasks/abc204_a) 题目大意 输入格式 输出 ...

  5. AtCoder Beginner Contest 198 A~E题解

    ABC198 A~E [A - Div](https://atcoder.jp/contests/abc198/tasks/abc198_a) 题目大意 输入格式 输出格式 样例 分析 代码 [B - ...

  6. Mynavi Programming Contest 2021 (AtCoder Beginner Contest 201) A~E 题解

    ABC201/Mynavi2021 A~E [A - Tiny Arithmetic Sequence](https://atcoder.jp/contests/abc201/tasks/abc201 ...

  7. AtCoder Beginner Contest 196 A~E题解

    ABC196 A~E [A - Difference Max](https://atcoder.jp/contests/abc196/tasks/abc196_a) 题目大意 输入格式 输出格式 样例 ...

  8. AtCoder Beginner Contest 260 A~F 题解

    ABC260 A~F [A - A Unique Letter](https://atcoder.jp/contests/abc260/tasks/abc260_a) 题目大意 输入格式 输出格式 样 ...

  9. AtCoder Beginner Contest 253 A~E 题解

    ABC253 A~E [A - Median?](https://atcoder.jp/contests/abc253/tasks/abc253_a) 题目大意 输入格式 输出格式 样例 分析 代码 ...

最新文章

  1. 2020秋季-人工神经网络课程报告
  2. IOS CALayer
  3. 精准扶贫探索新融合模式-农业大健康·李龙:谋定乡村振兴
  4. 企业建立数据驱动决策该如何做?终于有大神总结全了
  5. Qt QSetting *.ini.lock
  6. 使用Apriori进行关联分析(一)
  7. url参数拼接 php,PHP解析url并得到url参数方法总结
  8. java技术秘籍 转摘
  9. ARCH与GARCH模型
  10. 动态组合sql语句详解
  11. 秩和比(RSR)指标计算
  12. vue3 ts three 动画 骨骼动画 人物动画 模型动画
  13. SDL 加载显示JPEG图片
  14. c语言程序运行超时是怎么回事,这个运行超时是什么原因?求助~
  15. 微信小程序导入Bmob后端云的步骤
  16. Ashen的成长,从CSDN博客开始!
  17. X86_64 GNU汇编、寄存器、内嵌汇编
  18. 23-1-18 PDManer 工具
  19. gitHub不能用密码推送了,必须要使用令牌
  20. 嵌入式Linux驱动编程复习资料

热门文章

  1. 如何打开7z格式的压缩文件?
  2. badboy录制时弹框提示“当前页面的脚本发生错误”
  3. 智能媒体、大数据与知识发现国际会议(IMBDKM 2023)诚邀学者关注、参与
  4. 银汇通无线pos机简介
  5. 工科生简历实例计算机,工科毕业生简历范文
  6. 什么是EOS(不一样的角度看柚子)
  7. 上海一女子楼道内被捅死 目前警方已介入调查
  8. 网上虚拟展厅制作方案及流程
  9. Think PHP 5 定时任务
  10. C++面向对象实验(四)