Codeforces Round 986 (Div. 2)题解记录(A~D)

news/2024/11/12 18:02:50/文章来源:https://www.cnblogs.com/cjcf/p/18538853

不知道cf重新交通过会重新算积分,直接多扣了300积分,真难绷,引以为戒吧
比赛链接:https://codeforces.com/contest/2028

A. Alice's Adventures in "Chess"

爱丽丝正试图在乡村与红皇后会面!目前,爱丽丝位于位置\((0, 0)\),红皇后位于位置\((a, b)\)。爱丽丝只能朝四个基本方向(北、东、南、西)移动。
更正式地说,如果爱丽丝在点\((x, y)\),她将执行以下操作之一:

  • 向北移动(用N表示),移动到\((x, y+1)\)
  • 向东移动(用E表示),移动到\((x+1, y)\)
  • 向南移动(用S表示),移动到\((x, y-1)\);或者
  • 向西移动(用W表示),移动到\((x-1, y)\)
    爱丽丝的移动是预先确定的。她有一个字符串\(s\),代表她从左到右执行的一系列移动。一旦她到达序列的末尾,她将永远重复相同的移动模式。
    你能帮爱丽丝计算出她是否最终会与红皇后相遇吗?

\(Input\)
每个测试包含多个测试用例。第一行包含测试用例的数量\(t\)\(1 \le t \le 500\))。测试用例的描述随后给出。
每个测试用例的第一行包含三个整数\(n\)\(a\)\(b\)\(1 \le n\)\(a\)\(b \le 10\))——字符串的长度和红皇后的初始坐标。
第二行包含一个长度为\(n\)的字符串\(s\),只由字符N,E,S或W组成。
\(Output\)
对于每个测试用例,输出一个字符串“YES”或“NO”(不带引号),表示爱丽丝最终是否会与红皇后相遇。
\(Sample\)
6
2 2 2
NE
3 2 2
NNE
6 2 1
NNEESW
6 10 10
NNEESW
3 4 2
NEE
4 5 5
NEWS


YES
NO
YES
YES
YES
NO

思路:她将永远重复相同的移动模式。这句话很重要,爱丽丝在一次循环中不一定会遇到红皇后,显然最坏每次循环后最坏移动0或1,因为数据范围很小直接重复循环1000次(多次)就好,看看是否遇到就好,这里脑抽,赛后一个多小时又交了一发

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll                                     long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
int main()
{fio();ll t;cin>>t;while(t--){ll n,a,b;cin>>n>>a>>b;string f;cin>>f;ll cnt,ans;cnt=ans=0;ll pd=0;ll i=0;ll gs=4000;while(1){if(cnt==a&&ans==b){pd=1;break;}gs--;if(gs==0)break;if(f[i]=='N'){ans++;}else if(f[i]=='S'){ans--;}else if(f[i]=='E'){cnt++;}else if(f[i]=='W')cnt--;i++;if(i==n){i=0;}}if(pd)cout<<"YES"<<endl;else cout<<"NO"<<endl;}
}

B. Alice's Adventures in Permuting

爱丽丝把“变换”和“排列”这两个词搞混了!她有一个由三个整数\(n\)\(b\)\(c\)定义的数组\(a\):数组\(a\)的长度为\(n\),由\(a_i = b \cdot (i - 1) + c\)给出,对于\(1 \le i \le n\)。例如,如果\(n=3\)\(b=2\)\(c=1\),那么\(a=[2 \cdot 0 + 1, 2 \cdot 1 + 1, 2 \cdot 2 + 1] = [1, 3, 5]\)
现在,爱丽丝非常喜欢\([0, \ldots, n-1]\)的排列\(^{\text{∗}}\),并且希望将\(a\)转换成一个排列。在一次操作中,爱丽丝用\(a\)\(\operatorname{MEX}\)\(^{\text{†}}\)替换\(a\)中的最大元素。如果\(a\)中有多个最大元素,爱丽丝选择最左边的一个进行替换。
你能帮爱丽丝计算出她需要进行多少次操作才能使\(a\)首次变成一个排列吗?如果不可能,你应该报告。
\(^{\text{∗}}\)长度为\(n\)的排列是一个由\(0\)\(n-1\)\(n\)个不同整数组成的数组,顺序任意。请注意,这与排列的常规定义略有不同。例如,\([1,2,0,4,3]\)是一个排列,但\([0,1,1]\)不是排列(\(1\)在数组中出现了两次),\([0,2,3]\)也不是排列(\(n=3\)但数组中有\(3\))。
\(^{\text{†}}\)一个数组的\(\operatorname{MEX}\)是不属于该数组的最小的非负整数。例如,\([0, 3, 1, 3]\)\(\operatorname{MEX}\)\(2\)\([5]\)\(\operatorname{MEX}\)\(0\)
\(Input\)
每个测试包含多个测试用例。第一行包含测试用例的数量\(t\)\(1 \le t \le 10^5\))。随后是测试用例的描述。
每个测试用例只有一行,包含三个整数\(n\)\(b\)\(c\)\(1\le n\le 10^{18}\)\(0\le b\)\(c\le 10^{18}\))——数组的参数。
\(Output\)
对于每个测试用例,如果数组永远无法变成一个排列,输出\(-1\)。否则,输出使数组变成排列的最小操作次数。
\(Sample\)
7
10 1 0
1 2 3
100 2 1
3 0 1
3 0 0
1000000000000000000 0 0
1000000000000000000 1000000000000000000 1000000000000000000


0
1
50
2
-1
-1
1000000000000000000

思路:给的序列其实是个以c为初项,以b为公差的等差数列,

1.首先思考下不可能条件吧:如果对于目前最右边的最大数,每次变换后仍然是他最大就是不可能情况,对于一个公差不为0的等差数列,显然是不会出现这种情况的

所以思考公差为0的情况,枚举下初项为1,4可发现,如果c+1<n-1一定无解

2.有解次数,如何最小化?

其实只要看在这个序列中多个已经符合n排列的数的种类就行了,

如n=4,b=2,c=0时排列一开始为0 2 4 6,显然,对于每个不符合的数每次会变成符合的数,而且符合的数他是不用变的(当只有一个时)

所以当b>0时,直接根据公式b*i+c<=n-1,求出i(c>n-1时,这里会得出i<0),否则i=0,然后如果c<=n-1,则i++,否则i不变,最后和n取个min就得出答案了

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll                                     long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
int main()
{fio();ll t;cin>>t;while(t--){ll n,b,c;cin>>n>>b>>c;if(b==0&&c+1<n-1){cout<<-1<<endl;continue;}else {ll gs=0;ll x=n-1;if(b>0)gs=(x-c)/b;if(c<=n-1)gs++;cout<<min(n-gs,(ll)n)<<endl;}}
}

C. Alice's Adventures in Cutting Cake

爱丽丝在疯帽子的茶会上!有一个由\(n\)节组成的长蛋糕,每节的美味值分别为\(a_1, a_2, \ldots, a_n\)。茶会上有\(m\)个生物,不包括爱丽丝。
爱丽丝将把蛋糕切成\(m + 1\)块。形式上,她将蛋糕分成\(m + 1\)个子数组,每个子数组由一些相邻的部分构成。一块蛋糕的美味度是其各节美味度的总和。之后,她将这\(m + 1\)块蛋糕分给\(m\)个生物和她自己(她的那块可以是空的)。然而,每个\(m\)个生物只有在其蛋糕块的美味度至少为\(v\)时才会感到满意。
爱丽丝希望确保每个生物都满意。在这一条件下,她还希望最大化她自己那块蛋糕的美味度。你能帮爱丽丝找到她那块蛋糕的最大美味度吗?如果没有办法确保每个生物都满意,请输出\(-1\)
\(Input\)
每个测试包含多个测试用例。第一行包含测试用例的数量\(t\)\(1 \le t \le 10^4\))。随后是测试用例的描述。
每个测试用例的第一行包含三个整数\(n, m, v\)\(1\le m\le n\le 2\cdot 10^5\)\(1\le v\le 10^9\))——蛋糕的节数、生物的数量以及每个生物对美味度的最小要求。
下一行包含\(n\)个空格分隔的整数\(a_1, a_2, \ldots, a_n\)\(1 \le a_i \le 10^9\))——各节蛋糕的美味度。
所有测试用例中\(n\)的总和不超过\(2\cdot 10^5\)
\(Output\)
对于每个测试用例,输出爱丽丝能够获得的最大美味度,或者如果没有办法确保每个生物都满意,则输出\(-1\)
\(Sample\)
7
6 2 1
1 1 10 1 1 10
6 2 2
1 1 10 1 1 10
6 2 3
1 1 10 1 1 10
6 2 10
1 1 10 1 1 10
6 2 11
1 1 10 1 1 10
6 2 12
1 1 10 1 1 10
6 2 12
1 1 1 1 10 10


22
12
2
2
2
0
-1

思路:我们一开始肯定无法直接知道从什么点开始到什么点结束为爱丽丝能拿的最大美味度,所以既然我不知道,那我每个都试试呗

首先用前缀和后缀数组wz1,wz2处理好到某个点能有多少个人被分配好蛋糕,还要用另一个前缀数组pre处理好前缀和,随后将后缀数组转成正序数组,然后每到i就知道已经分好了wz1[i-1]个人,所以还要分m-wz1[i-1]个人,直接二分(lower_bound)那个正序数组找到第一个符合的下标i1,然后n-i1,(记得二分包含0位置哦),即可得到爱丽丝在符合题意状况下能拿到的区间蛋糕(pre[n-i1]-pre[i-1]),在所有可能中取个最大值就好

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll                                     long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
ll pre[250000];
ll sub[250000];
ll wz1[250000];
ll wz2[250000];
ll a[250000];
ll ok[250000];
int main()
{fio();ll t;cin>>t;while(t--){ll n,m,v;cin>>n>>m>>v;for(ll i=1;i<=n;i++)cin>>a[i],sub[i]=0,pre[i]=0,wz1[i]=0,wz2[i]=0;sub[n+1]=0;ll sum=0;for(ll i=1;i<=n;i++){sum+=a[i];pre[i]=pre[i-1]+a[i];wz1[i]=max(wz1[i],wz1[i-1]);if(sum>=v){sum=0;wz1[i]++;}}sum=0;wz2[n+1]=0;for(ll i=n;i>=1;i--){sum+=a[i]; wz2[i]=max(wz2[i],wz2[i+1]);if(sum>=v){wz2[i]++;sum=0;}ok[n-i+1]=wz2[i];}//  cout<<wz1[n]<<endl;if(wz1[n]<=m-1){cout<<-1<<endl;}else {ll ans=0;for(ll i=1;i<=n;i++){ll x=wz1[i-1];ll u=m-x;ll op=lower_bound(ok,ok+1+n,u)-ok;ans=max(ans,pre[n-op]-pre[i-1]);}cout<<ans<<endl;}}
}

D. Alice's Adventures in Cards
爱丽丝正在和红心皇后、红心国王以及红心杰克玩牌。在他们的牌游戏中有\(n\)种不同类型的牌。爱丽丝目前有一张类型为\(1\)的牌,并且需要一张类型为\(n\)的牌才能逃离仙境。其他玩家每人都有每种类型的一张牌。
在这个牌游戏中,爱丽丝可以和另外三个玩家交换牌。每个玩家对\(n\)种类型的牌有不同的偏好,这可以通过排列\(q\)\(k\)\(j\)来描述,分别对应皇后、国王和杰克的偏好。
如果对于玩家的排列\(p\)\(p_a > p_b\),那么这个玩家更看重牌\(a\)而不是牌\(b\)。然后,这个玩家愿意用牌\(b\)和爱丽丝交换牌\(a\)。爱丽丝的偏好很直接:如果\(a > b\),她就更看重牌\(a\)而不是牌\(b\),而且她也只会根据这些偏好进行交易。
确定爱丽丝是否可以根据这些偏好,从类型为\(1\)的牌交易到类型为\(n\)的牌,如果可能的话,请给出一组可能的交易方式。
\(^{\text{∗}}\)长度为\(n\)的排列是一个由\(n\)个不同的整数组成的数组,这些整数从\(1\)\(n\),顺序任意。例如,\([2,3,1,5,4]\)是一个排列,但\([1,2,2]\)不是排列(\(2\)出现了两次),而且\([1,3,4]\)也不是排列(\(n=3\)但数组中有\(4\))。
\(Input\)
每个测试包含多个测试用例。第一行包含测试用例的数量\(t\)\(1 \le t \le 10^4\))。
每个测试用例的第一行包含一个整数\(n\)\(2\le n\le 2\cdot 10^5\))——牌的类型数量。
接下来的三行包含皇后、国王和杰克的偏好。这些行每行包含\(n\)个整数\(p_1, p_2, \ldots, p_n\)\(1\le p_i\le n\))——对应玩家偏好的排列。
所有测试用例中\(n\)的总和不超过\(2\cdot 10^5\)
\(Output\)
对于每个测试用例,在第一行输出一个字符串"YES"或"NO"(不包括引号),表示爱丽丝是否可以交易到牌\(n\)
如果第一行是"YES",那么在下一行输出\(k\)——爱丽丝将进行的交易次数。在接下来的\(k\)行中,输出空格分隔的一个字符\(c\in \{\texttt{q}, \texttt{k}, \texttt{j}\}\)和一个整数\(x\),表示爱丽丝与玩家\(c\)交易以获得牌\(x\)。必须满足在第\(k\)行,\(x = n\)。如果有多个解决方案,请打印任何一个。
你可以以任何情况(大写或小写)输出这个答案。例如,字符串"yEs"、"yes"、"Yes"和"YES"将被视为肯定的回应。同样,表示交易中玩家的字符\(c\)\(\texttt{Q}, \texttt{K}, \texttt{J}\)将与它们的小写变体一起被接受)。
\(Sample\)
2
3
1 3 2
2 1 3
1 2 3
4
2 3 1 4
1 2 3 4
1 4 2 3


YES
2
k 2
q 3
NO

思路:由答案可知,我得输出过程,所以一定是dfs或者bfs,思考下bfs,其实显然不行,因为过程会有问题(数据储存量会太大),所以就dfs了,一开始想建边,但是明显\(n^2\)的时间复杂度,所以否决,然后想了下题目给了两个约束,即优先度,和爱丽丝只能换更大的数,显然如果我dfs,一个数搜过了,之后一定不会搜了,所以准备记忆化+dfs,然后在想的时候优化了下遍历时间,一开始用3个set根据权值(优先度)对于q,k,j的手牌进行排序,随后开了两个二维数组,一个记录对应数的位置,还有一个记录排序后的数随后直接dfs+记忆化(这里用的是两个二维数组)就过了,但是时间是1468ms,有点危险,看了下样例全是NO才是1468ms,其他都是<900ms就过了,所以如果要优化下,看下能否特判不行情况吧,这里也脑抽重新交了一发,积分--,具体时间复杂度自己也不清楚

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll                                     long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
set<pair<ll,ll>>q[4];
bool vis[250000];
vector<pair<char,ll>>ans;
ll pd=0;
ll n;
ll a[4][250000];
ll b[4][250000];
void dfs(ll x)
{ vis[x]=1;if(x==n){pd=1;return ;}ll wz;wz=a[1][x];// ll op=0;for(ll i=wz+1;i<=n;i++){if(b[1][i]>x&&vis[b[1][i]]==0){ans.push_back({'q',b[1][i]});dfs(b[1][i]);if(pd)return ;ans.pop_back();}}wz=a[2][x];for(ll i=wz+1;i<=n;i++){if(b[2][i]>x&&vis[b[2][i]]==0){ans.push_back({'k',b[2][i]});dfs(b[2][i]);if(pd)return ;ans.pop_back();}}  wz=a[3][x];for(ll i=wz+1;i<=n;i++){if(b[3][i]>x&&vis[b[3][i]]==0){ans.push_back({'j',b[3][i]});dfs(b[3][i]);if(pd)return ;ans.pop_back();}}
}
int main()
{fio();ll t;cin>>t;while(t--){pd=0;cin>>n;ans.clear();q[1].clear();q[2].clear();q[3].clear();for(ll i=1;i<=3;i++){for(ll j=1;j<=n;j++){ll w;cin>>w;vis[w]=0;q[i].insert({n-w+1,j});}ll cnt=0;for(auto j:q[i]){cnt++;a[i][j.second]=cnt;b[i][cnt]=j.second;}}dfs(1);if(pd==0){cout<<"NO"<<endl;}else {cout<<"YES"<<endl;cout<<ans.size()<<endl;for(auto j:ans){cout<<j.first<<" "<<j.second<<endl;}}}
}

E. Alice's Adventures in the Rabbit Hole

思路:赛时没调出来,但是先给个想法吧,仅供参考,就是以1为根节点,然后回溯时进行失败概率和计算,最后输出时,用mod-失败概率即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/831109.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【CodeForces训练记录】Codeforces Round 986 (Div. 2)

训练情况赛后反思 C题逆风翻盘,可能勉强青名了。A题愣神了,我觉得还能再做的快一点。 A题 给定一个字符串,NWSE,重复着字符串走,我们直接模拟即可,用 while 来判断是否走到终点,然后对于不可能走到的终点,我选择了一个不会超时的步数范围,超出就跳出 while 即可,最后…

24. 使用MySQL之使用游标

1. 游标 由前几章可知,MySQL检索操作返回一组称为结果集的行。这组返回的行都是与SQL语句相匹配的行(零行或多行)。 使用简单的SELECT语句,例如,没有办法得到第一行、下一行或前10行,也不存在每次一行地处理所有行的简单方法(相对于成批地处理它们)。 有时,需要在检索…

Python clickhouse-driver 类库使用学习总结

实践环境 python3 .9.13 clickhouse-driver 0.2.9 实践操作 # -*- coding:utf-8 -*-import clickhouse_driverif __name__ == __main__:host = 192.168.88.131port = 9000 # 注意,不能使用默认的8123username = testaccpassword = test1234database = default# 连接方式1# con…

随波逐流工具使用_Week1

跟着大师傅的公众号做题的week1 来源以及说明 (文章主要是了解怎样使用长弓三皮大师傅的随波逐流工具,wp以及附件来自大师傅长弓三皮) (这周主要是做笔记的软件老是出现问题,有一些笔记有点乱,后面慢慢改进) 软件及题目下载 http://www.1o1o.xyz/bo_softdown.html CTF题目wr…

开源 - Ideal库 - 特殊时间扩展方法(三)

分享特殊时间获取的扩展方法,包括当天开始/结束时间、当前周/月/季度/年的第一天和最后一天等,附代码示例和单元测试,库将上传至Nuget,源码在代码库。书接上回,我们继续来分享一些关于特殊时间获取的常用扩展方法。01、获取当天的开始时间 当天的开始时间指00:00:00时刻,…

Vue2: v-for 联合 ref 使用, 对应引用信息为数组

MarkTime: 2024-06-03 00:21:47 LogTime: 2024-11-10 23:25:35说明问题:调用ref引用的时候, 好奇获取的时候为什么 有的返回的是对象, 有的返回的是数组 (如下图)版本:vue: 2.6.14源码 <!--已经省略掉大部分代码 只保留结构为说明 --> <template><div class=&qu…

Debug: setTimeout 使用做定时器时的错误函数传递方式

MarkTime: 2024-05-24 10:41:26 LogTime: 2024-11-10 14:55:53首先复习 setTimeout(): 语法: let timeId = setTimeout(func|code, [delay_millisecond]) 说明: 延时器. 延迟delay_millisecond后, 执行参数1setInterval(): 语法: let timeId = setInterval(func|code, [delay_…

Debug: calc() 未生效 = 内嵌样式表达式需使用空格分隔

MarkTime: 2024-06-25 17:10 LogTime: 2024-11-09 13:58:02结论calc()内的表达式 需要使用 空格分隔符, 即 更正 calc(100%-100px-10px); => calc(100% - 100px - 10px); 即可源<!-- 原错误代码 --> <div class="layout-search" style="width: 100%…

[云研发]腾讯云cloudstudio使用教程-记录1

cloudstudio在vscode中新建终端,使用nvidia-smi查看显卡与gpu情况,可知当前使用的显卡是T4的,显存有15GTalk is cheap. Show me the code

rip

题目链接:rip。 IDA 打开附件,进入到 main 函数,反编译后如下。留意到存在 gets 函数,因此存在栈溢出漏洞,经过动态调试,确定在输入 0x17 个字符后,即可覆盖到返回地址。同时,留意到存在 fun 函数,如下。因此,直接将程序执行流劫持到 fun 函数,即可 GetShell(此处需…

test_your_nc

题目链接:test_your_nc。 打开附件,进入 main 函数,IDA 反编译如下。因此直接连接即可 GetShell。

【docker应用】从Docker(k8s)镜像或者容器里提取jar包

引言 在docker或者k8s上运行了第三方的应用,很多时候我们都想知道运行流程,一般都会docker或者k8s容器中获取jar包。 那么该如何把里面的jar包提取出来呢? 其实有两种方式,分别为: 从镜像信息获取 进入容器获取从镜像信息获取 首先,查看镜像: docker image ls |grep <…