首页 > 其他分享 >Educational Codeforces Round 141 (Rated for Div. 2) A-C题解

Educational Codeforces Round 141 (Rated for Div. 2) A-C题解

时间:2023-01-09 16:55:17浏览次数:61  
标签:node Educational Rated return int 题解 cin 敌人 我们

比赛链接

A、Make it Beautiful

一种构造方法:按照从大到小的顺序构造,可以发现前缀和永远大于当前值。但是需要特判存在两个最大值的情况。只需要将最小值与第二位交换位置即可。最后暴力判一遍防止数字全部相等。

点击查看代码
#include<bits/stdc++.h>
using namespace std;

bool cmp(int a, int b){
    return a > b; 
}

int a[100010]; 
int b[100010]; 

int main(){
    int T; 
    cin >> T;
    while(T--){
        int n; 
        cin >> n; 
        for(auto i = 1; i <= n; i++)
            cin >> a[i];
        sort(a + 1, a + n + 1, cmp); 
        if(a[1] == a[2]){
            b[1] = a[1]; 
            b[2] = a[n]; 
            for(int i = 3; i <= n; i++)
                b[i] = a[i-1]; 
        }
        else for(int i = 1; i <= n; i++) b[i] = a[i]; 
        int sum = 0; 
        bool flag = 1; 
        for(int i = 1; i <= n; i++){
            if(b[i] == sum){
                flag = 0; 
                break; 
            }
            sum += b[i]; 
        }
        if(flag){
            puts("YES"); 
            for(int i = 1; i <= n; i++)
                printf("%d ", b[i]); 
            cout << endl; 
        }
        else puts("NO"); 
    }
    return 0; 
}

B、Matrix of Differences

纯智商题。可以发现最大值一定是 \(n^2 - 1\) 种,即 \([1, n^2 - 1]\) 中的所有整数都会出现。于是考虑最大与最小挨着构造(只有这样才能出现差值为 \(n^2 - 1 、n^2 - 2 ......\) 的情况)。
那么考虑斜对角线交替放数,一条线从小到大,一条线从大到小,依次放入。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define N 100010

int a[51][51]; 

int main(){
    int T; cin >> T;
    while(T--){
        int n; cin >> n; 
        memset(a, 0, sizeof(a)); 
        a[1][1] = 1; 
        int del = 1;
        bitset <10010> vis(0);  
        int now = 1; int now2 = n * n; 
        for(int i = 1; i <= n; i++){
            int x = i, y = 1; 
            
            if(i % 2 == 0){
                while(x >= 1 && y <= n){
                    a[x][y] = now; 
                    now++; 
                    x--, y++; 
                }
            }
            else{
                while(x >= 1 && y <= n){
                    a[x][y] = now2; 
                    now2--;
                    x--, y++; 
                }
            }
        }

        for(int i = 2; i <= n; i++){
            int x = n, y = i; 
            
            if(i % 2 != (n % 2)){
                while(x >= 1 && y <= n){
                    a[x][y] = now; 
                    now++; 
                    x--, y++; 
                }
            }
            else{
                while(x >= 1 && y <= n){
                    a[x][y] = now2; 
                    now2--;
                    x--, y++; 
                }
            }
        }
        
        for(int i = 1; i <= n; i++, puts("")){
            for(int j = 1; j <= n; j++){
                printf("%d ", a[i][j]); 
            }
        }
    }
    return 0; 
}

C、Yet Another Tournament

(摘编自自己的洛谷题解)

题目大意

首先容易推出假如不算我们自己,那么剩下的敌人的得分就是数列 \(a_i = i\)。现在我们要做的就是花一定数量的时间来训练对应一部分敌人,打败他们同时自己获得一分(当然被打败的那个敌人就少获得一分)。

主要思路

容易想到我们肯定是想要自己的分尽量高,那么显然就是贪心,从小到大选择花费时间最小的敌人,一直到总和超过 \(m\) 为止。但存在一个问题,就是未被我们选中的敌人会增加 \(1\) 分。下面就此进行讨论。

假设我们按照贪心的方法选择了 \(k\) 个敌人进行训练,那么容易知道 \(k\) 就是我们自身的最大得分。假设有一敌人的初始得分大于 \(k\), 那我们完全就可以忽略他。因为显而易见的是无论我们如何“努力”,我们都不可能战胜他。对于初始得分小于 \(k\) 的敌人,显然排名永远会落后我们。所以,我们只需要考虑剩下一个唯一情况,就是初始得分等于 \(k\) 的人。假设我们在保持总分不变的情况下没有选择战胜他,那么我们就会损失一个排名。所以尝试将该人与最大值进行交换,尽可能选中他。

正确性

下面简略说一下上述方法的正确性(最优性)。假设我们的得分为 \(k\), 那么我们能战胜的敌人就是 \(k\) 个(不算临界情况)。如果我们能将临界者战胜,就是 \(k+1\) 个。如果为了加入当前临界者而导致 \(k\) 减少一,显然也不优。所以最大化 \(k\) 并尽量拉入临界者是最优做法。

代码时间

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define N 500010

int n, m; 

struct node{
    int w, id; 
} t[N]; 
int a[N]; 
int b[N];

bool cmp1(node a, node b){
    return a.w < b.w; 
}

int main(){
    int T; cin >> T; 
    while(T--){
        cin >> n >> m; 
        for(int i = 1; i <= n; i++){
            cin >> t[i].w;
            t[i].id = i; 
            a[i] = t[i].w; 
        } 
        sort(t + 1, t + n + 1, [](node a, node b){
            return a.w < b.w; 
        }); 
        bitset <N> vis(0); 
        int sum = 0, maxn = n, ans = 0; 
        for(int i = 1; i <= n; i++){
            if(sum + t[i].w > m){
                maxn = i-1; 
                break; 
            } 
            sum += t[i].w;
            vis[t[i].id] = 1; 
            ans++; 
        }
        if(!vis[ans+1]){
            if(sum - t[maxn].w + a[ans+1] <= m){
                vis[ans+1] = 1;
                vis[t[maxn].id] = 0; 
            }
        }
        for(int i = 1; i <= n; i++)
            b[i] = i - 1 + (!vis[i]);
        b[n+1] = ans; 
        sort(b + 1, b + n + 2, [](int a, int b) -> bool {return a > b; });  // 排序计算排名
        int num = 0; 
        for(int i = 1; i <= n + 1; i++){
            num++; 
            if(b[i] == ans){
                break; 
            }
        }
        cout << num << endl; 
    }
    return 0; 
}

标签:node,Educational,Rated,return,int,题解,cin,敌人,我们
From: https://www.cnblogs.com/wondering-world/p/17037539.html

相关文章

  • P5999 [CEOI2016] kangaroo 题解
    分析一个妙妙的trick。首先原题可以转化成求有多少\(1\simn\)的排列\(p\)满足\(\foralli\in(1,n)\),\(p_i\)两边的数同时小于或大于\(p_i\),且\(p_1=s,p_n=t\)......
  • WC 2018 题解
    A若干套路拼起来的胖题。设这三棵树分别是\(T_1,T_2,T_3\)。沿用“CTSC2017暴力写挂”的思路,对第一棵树点分治,此时要处理的是以\(u\)为中心的一块在\(T_1\)上的连......
  • CF652F 题解
    题意传送门在一个长度为\(m\)的圆环上有\(n\)只初始位置互不相同的蚂蚁,每只蚂蚁的速度都为\(1\),初始方向为顺时针或逆时针;两只运动方向不同的蚂蚁相遇时会调转方向,......
  • Educational Codeforces Round 141
    A.MakeitBeautiful他想要变美,我们按照题目说的做就行,通过判断我们发现如果在sort一遍后sort(a+1,a+1+n);if(a[1]==a[n]){cout<<"NO"<<"\n";......
  • Codeforces 1671 F Permutation Counting 题解
    题目链接把\(p_i>p_{i+1}\)的位置个数称为间隔数首先想到一个暴力做法。从小到大挨个添加1-n中的每个数,注意到添加数i时,只能添加到当前序列的最后11个位置中,否则逆序对数......
  • 2018年各大赛事题解
    大多数题解都是口胡,不保证正确性,有错请指出,谢谢。CQOI2018除了“交错序列”和“九连环”两道数学题以外,全是板子题,遭不住了。破解D-H协议BSGS板子题,时间复杂度\(\m......
  • Atcoder ABC284 前五题题解
    ABC284A-SequenceofStrings题意:有n个字符串\(s_1,s_2,s_3,...,s_n\),要求按\(n,n-1,n-2,...,1\)的顺序输出样例:输入3TakahashiAokiSnuke输出......
  • Codeforces 1305 F Kuroni and the Punishment 题解 (随机算法)
    题目链接首先注意到每个数最多操作1次就能让他变成2的倍数,所以答案\(\len\)。如果我们能枚举[1,1e12]中所有的质数,并对每个质数p求出把数组中所有数都变成它的倍数的最少......
  • 【题解】P5666 [CSP-S2019] 树的重心
    感觉对重心的理解更直观了一点。题意求一棵树上删去每一条边后两侧子树重心的编号和。\(n\leq3\times10^5\)思路神奇的清真数论。首先这里有一步很妙的操作:把整......
  • LeetCode 887. 鸡蛋掉落-题解分析
    题目来源887.鸡蛋掉落题目详情给你k枚相同的鸡蛋,并可以使用一栋从第1层到第n层共有n层楼的建筑。已知存在楼层f,满足 0<=f<=n,任何从高于f的楼层落......