概述
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
构造a数组为1,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
注意到n最大只有5000
长
度
为
1
的
子
数
组
有
n
个
长度为1的子数组有n个
长度为1的子数组有n个
长
度
为
2
的
子
数
组
有
n
−
1
个
长度为2的子数组有n-1个
长度为2的子数组有n−1个
.
.
.
.
.
.
.
.......
.......
长
度
为
n
的
子
数
组
有
1
个
长度为n的子数组有1个
长度为n的子数组有1个
所
以
一
共
有
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'
只包含′D′或者′R′
答
案
必
定
为
n
答案必定为n
答案必定为n
同
时
包
含
′
D
′
和
′
R
′
同时包含'D'和'R'
同时包含′D′和′R′
无
非
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+1位置开始还有多少个′D′字符
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;
}
最后
以上就是风中面包为你收集整理的Educational Codeforces Round 123 (Rated for Div. 2) A-E题解的全部内容,希望文章能够帮你解决Educational Codeforces Round 123 (Rated for Div. 2) A-E题解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复