0
点赞
收藏
分享

微信扫一扫

Educational Codeforces Round 123 (Rated for Div. 2) A-E题解

郝春妮 2022-02-23 阅读 66

A. Doors and Keys

E题还在施工中
思路
模 拟 即 可 模拟即可
时间复杂度 O n On On

#include <bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define der(i,a,b) for(re i = a ; i >= b ; -- i)
#define cf int _; cin>> _; while(_--)
#define sf(x) scanf("%lld",&x)
#define pll pair<int,int> 
#define re register int
#define int long long 
#define y second 
#define x first 
using namespace std;
inline void de(auto x) {cout << x << "\n" ;}
const int N = 1e6 + 10 , M = 3010 , mod = 998244353  ;

signed main()
{
    cf
    {
        string s ;
        cin >> s ;
        int a = 0 , b = 0 , c = 0 ;
        int f1 = 0 ;
        for(auto i : s)
        {
            if(i == 'r') a ++ ;
            else if(i == 'g') b ++ ;
            else if(i == 'b') c ++ ;
            else if(i == 'R')
            {
                if(a >= 1) a -- ;
                else f1 = 1 ;
            }
            else if(i == 'G')
            {
                if(b >= 1) b -- ;
                else f1 = 1 ;
            }
            else
            {
                if(c >= 1) c -- ;
                else f1 = 1 ;
            }
        }
        if(f1) puts("NO") ;
        else puts("YES") ;
    }
    return 0;
}

B. Anti-Fibonacci Permutation

思路
构 造 a 数 组 为 1 , 3 , 2 , 4 , 5..... n 构造a数组为1,3,2,4,5.....n a1,3,2,4,5.....n
n e x t − p e r m u t a t i o n 暴 力 判 断 输 出 即 可 next-permutation暴力判断输出即可 nextpermutation
时间复杂度 O n On On

#include <bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define der(i,a,b) for(re i = a ; i >= b ; -- i)
#define cf int _; cin>> _; while(_--)
#define sf(x) scanf("%lld",&x)
#define pll pair<int,int> 
#define re register int
#define int long long 
#define y second 
#define x first 
using namespace std;
inline void de(auto x) {cout << x << "\n" ;}
const int N = 1e6 + 10 , M = 3010 , mod = 998244353  ;

int a[N] ;
 
signed main()
{
    cf
    {
        int n ;
        cin >> n ;
        fer(i,1,n) a[i] = i ;
        swap(a[2],a[3]) ;
        int k = n ;
        while(next_permutation(a + 1 , a + 1 + n))
        {
            int f1 = 0 ;
            fer(i,3,n)
            {
                if(a[i] == a[i - 1] + a[i - 2])
                {
                    f1 = 1 ;
                }
            }
            if(!f1)
            {
                k -- ;
                for(int i = 1 ; i <= n ; i ++) cout << a[i] << " " ;
                puts("") ;
            }
            
            if(!k) break ;
        }
    }
    return 0;
}

C. Increase Subarray Sums

思路
首 先 f ( i ) = m a x ( f ( i ) , f ( i − 1 ) ) 首先f(i) = max(f(i),f(i-1)) f(i)=max(f(i),f(i1))

注 意 到 n 最 大 只 有 5000 注意到n最大只有5000 n5000
长 度 为 1 的 子 序 列 有 n 个 长度为1的子序列有n个 1n
长 度 为 2 的 子 序 列 有 n − 1 个 长度为2的子序列有n-1个 2n1
. . . . . . . ....... .......
长 度 为 n 的 子 序 列 有 1 个 长度为n的子序列有1个 n1
所 以 一 共 有 n ∗ ( n + 1 ) / 2 个 子 序 列 所以一共有n*(n+1)/2个子序列 n(n+1)/2

对 于 f ( i ) 来 说 , 选 i 个 数 + = x 对于f(i)来说,选i个数+=x f(i),i+=x
我 们 可 以 选 择 所 有 长 度 > = i 的 子 序 列 的 和 + = i ∗ x 我们可以选择所有长度>=i的子序列的和+=i*x >=i+=ix

设 v [ i ] 数 组 为 所 有 长 度 > = i 的 子 序 列 的 和 的 最 大 值 设v[i]数组为所有长度>=i的子序列的和的最大值 v[i]>=i
求 所 有 子 序 列 的 和 可 以 用 前 缀 和 优 化 求所有子序列的和可以用前缀和优化

那 么 答 案 即 为 f ( i ) = m a x ( v [ i ] + i ∗ x , f ( i − 1 ) ) 那么答案即为f(i)=max(v[i]+i*x,f(i-1)) f(i)=max(v[i]+ix,f(i1))

时间复杂度 O n 2 On^2 On2

#include <bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define der(i,a,b) for(re i = a ; i >= b ; -- i)
#define cf int _; cin>> _; while(_--)
#define sf(x) scanf("%lld",&x)
#define pll pair<int,int> 
#define re register int
#define int long long 
#define y second 
#define x first 
using namespace std;
inline void de(auto x) {cout << x << "\n" ;}
const int N = 1e6 + 10 , M = 3010 , mod = 998244353  ;

int n ;
int a[N] , s[N] , v[N] , x ;
 
signed main()
{
    cf
    {
        cin >> n >> x ;
        fer(i,1,n) sf(a[i]) , s[i] = s[i - 1] + a[i] , v[i] = -1e9 ;
        v[0] = 0 ;
        fer(len,1,n)
        {
            for(int i = 1 ; i + len - 1 <= n ; i ++)
            {
                int j = i + len - 1 ;
                v[len] = max(v[len] , s[j] - s[i - 1]) ;
            }
        }
        der(i,n-1,0) v[i] = max(v[i + 1] , v[i]) ;
        int res = 0 ;
        fer(i,0,n)
        {
            res = max(res , v[i] + i * x) ;
            cout << res << ' ' ;
        }
        puts("") ;
    }
    
    return 0;
}

D. Cross Coloring

思路
首 先 注 意 到 题 目 所 说 首先注意到题目所说
新 颜 色 将 应 用 于 每 个 单 元 格 , 无 论 该 单 元 格 在 操 作 之 前 是 否 着 色 新颜色将应用于每个单元格,无论该单元格在操作之前是否着色

这 意 味 着 最 后 一 个 染 色 的 行 和 列 颜 色 永 远 不 变 , 贡 献 恒 为 k 这意味着最后一个染色的行和列颜色永远不变,贡献恒为k ,k
既 然 永 远 不 变 , 我 们 可 以 删 去 这 一 行 和 这 一 列 既然永远不变,我们可以删去这一行和这一列

所 以 我 们 可 以 倒 着 看 所 有 染 色 的 格 子 所以我们可以倒着看所有染色的格子
如 果 这 个 格 子 所 在 的 行 或 者 列 没 有 被 染 色 如果这个格子所在的行或者列没有被染色
说 明 我 们 可 以 删 去 这 一 行 或 者 这 一 列 说明我们可以删去这一行或者这一列
贡 献 为 k 贡献为k k

如 果 所 有 行 或 者 所 以 列 都 被 删 掉 , 在 染 色 没 有 贡 献 如果所有行或者所以列都被删掉,在染色没有贡献 ,
比 如 现 在 第 一 行 和 所 有 列 都 被 删 掉 了 比如现在第一行和所有列都被删掉了
你 在 删 第 二 行 你 会 发 现 第 二 行 已 经 被 删 掉 了 你在删第二行你会发现第二行已经被删掉了

答 案 即 为 上 述 贡 献 累 乘 即 可 答案即为上述贡献累乘即可

时间复杂度 O n l o g n Onlogn Onlogn

#include <bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define der(i,a,b) for(re i = a ; i >= b ; -- i)
#define cf int _; cin>> _; while(_--)
#define sf(x) scanf("%lld",&x)
#define pll pair<int,int> 
#define re register int
#define int long long 
#define y second 
#define x first 
using namespace std;
inline void de(auto x) {cout << x << "\n" ;}
const int N = 1e6 + 10 , M = 3010 , mod = 998244353  ;

int n , m , k , s ;
pll a[N] ;
 
signed main()
{
    cf
    {
        cin >> n >> m >> k >> s ;
        int res = 1 ;
        
        map<int,int> hh , tt ;
        fer(i,1,s) cin >> a[i].x >> a[i].y ;
        int h = 0 , t = 0 ;
        
        der(i,s,1)
        {
            if(h == n || t == m) break ;
            int f1 = 0 ;
            if(!hh[a[i].x])
            {
                f1 = 1 ;
                hh[a[i].x] = 1 ;
                h ++ ;
            }
            if(!tt[a[i].y])
            {
                f1 = 1 ;
                tt[a[i].y] = 1 ;
                t ++ ;
            }
            
            if(f1)
                res = res * k % mod;
            
        }
        
        cout << res << "\n" ;
    }
    return 0;
}
举报

相关推荐

0 条评论