IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Educational Codeforces Round 123 (Rated for Div. 2) A-E题解 -> 正文阅读

[数据结构与算法]Educational Codeforces Round 123 (Rated for Div. 2) A-E题解

A. Doors and Keys

思路
模 拟 即 可 模拟即可
时间复杂度 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暴力判断输出即可 next?permutation
时间复杂度 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 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(i?1))

注 意 到 n 最 大 只 有 5000 注意到n最大只有5000 n5000
长 度 为 1 的 子 数 组 有 n 个 长度为1的子数组有n个 1n
长 度 为 2 的 子 数 组 有 n ? 1 个 长度为2的子数组有n-1个 2n?1
. . . . . . . ....... .......
长 度 为 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+=i?x

设 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]+i?x,f(i?1))

时间复杂度 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;
}

E. Expand the Path

思路
求 该 机 器 人 在 n ? n 方 阵 中 可 以 到 达 的 点 的 数 量 求该机器人在n*n方阵中可以到达的点的数量 n?n
首 先 根 据 减 法 原 理 首先根据减法原理
可 以 到 达 的 点 的 数 量 = n ? n ? 无 法 到 达 的 点 的 数 量 可以到达的点的数量 = n * n - 无法到达的点的数量 =n?n?

现 在 的 问 题 在 于 如 何 求 无 法 到 达 的 点 的 数 量 现在的问题在于如何求无法到达的点的数量

对 s 字 符 串 进 行 分 类 讨 论 对s字符串进行分类讨论 s
只 包 含 ′ D ′ 或 者 ′ R ′ 只包含'D'或者'R' DR
答 案 必 定 为 n 答案必定为n n

同 时 包 含 ′ D ′ 和 ′ R ′ 同时包含'D'和'R' DR
无 非 2 种 情 况 无非2种情况 2
R R . . R R D . . . . 或 者 是 D D . . D D R . . . . . RR..RRD....或者是DD..DDR..... RR..RRD....DD..DDR.....
首先看 R R . . R R D . . . . RR..RRD.... RR..RRD....
在这里插入图片描述
图 中 的 j 含 义 有 误 ? 应 该 为 从 R + 1 位 置 开 始 还 有 多 少 个 ′ D ′ 字 符 图中的j 含义有误 -应该为从R+1位置开始还有多少个'D'字符 j?R+1D

D D . . . . . . D D R . . . . . 同 理 用 上 述 方 法 统 计 个 数 DD......DDR.....同理用上述方法统计个数 DD......DDR.....
答 案 即 为 n ? n ? s u m 答案即为n*n-sum n?n?sum
时间复杂度 O n l o g n [ n 为 字 符 串 长 度 ] Onlogn[n为字符串长度] Onlogn[n]

#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 , len ;
char s[N] ;

signed main()
{
    cf
    {
        cin >> n >> s + 1 ;
        len = strlen(s + 1) ;
        map<char,int> q ;
        fer(i,1,len) q[s[i]] ++ ;
        
        if(q.size() == 1) de(n) ;
        else
        {
            int R = 0 , D = 0 ;
            // R D 表示第一个R / D 的位置
            fer(i,1,len) 
                if(s[i] == 'R')
                {
                    R = i ;
                    break ;
                }
            fer(i,1,len)
                if(s[i] == 'D')
                {
                    D = i ;
                    break ;
                }
                
            int a = q['R'] , b = q['D'] , sum = (R - 1) * (n - 1) + (D - 1) * (n - 1) ;
            int j = a - 1 ;
            fer(i,R+1,len)
            {
                if (s[i] == 'D')
                    sum += j ;
                else {
                    j -- ;
                }
            }
            j = b - 1;
            fer(i,D+1,len)
            {
                if (s[i] == 'R')
                    sum += j ;
                else {
                    j -- ;
                }
            }
            cout << n * n - sum << "\n" ;
        }
    }
    return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-02-24 15:33:08  更:2022-02-24 15:33:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 16:37:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码