Codeforces Round #767 (Div. 2)(A B C D E F1 F2)
Posted 斗奋力努
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #767 (Div. 2)(A B C D E F1 F2)相关的知识,希望对你有一定的参考价值。
Codeforces Round #767 (Div. 2)(A B C D E F1 F2)
A. Download More RAM
题意:问最多可以有多大RAM,当前RAM大于等于a[i]时,可以使RAM增加b[i]
思路:暴力+贪心,就将n个RAM参照a[i]从小到大排序就行了。
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>PII;
const int N=1005;
int n,k;
PII a[N];
void solve()
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) scanf("%d",&a[i].first);
for(int i=1;i<=n;i++) scanf("%d",&a[i].second);
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
if(k>=a[i].first) k+=a[i].second;
printf("%d\\n",k);
int main()
int t;scanf("%d",&t);
while(t--) solve();
B. GCD Arrays
题意:在区间[l,r]中所有整数构成的集合中进行k次操作,每次操作是选择集合中的两次数,将他们删去,把他们的乘积加入集合。问最后集合所有数的gcd是否大于1
思路:因为初始是连续的数,所有我就直接猜了一下当集合中的奇数个数小于等于k时,或者集合初始只有一个数时(需要特判掉这个),就是YES,否则就是NO。(好像是保证奇偶结合还是啥的)
#include<bits/stdc++.h>
using namespace std;
int l,r,k;
void solve()
scanf("%d%d%d",&l,&r,&k);
int len;
if(l%2==1) len=(r-l+2)/2;
else len=(r-l+1)/2;
if(k>=len) puts("YES");
else if(l==r&&l!=1) puts("YES");
else puts("NO");
int main()
int t;scanf("%d",&t);
while(t--) solve();
C. Meximum Array
题意:给一个长度为n的序列a,每次从开头取一截数字,将该截数字删去,同时在b序列中加入这截数字的MEX,要求输出字典序最大的b序列
思路:直接记录每种数字的位置,循环时拿now代表当前需要的数字,①:如果还有该数字,就代表可以选到now,则now+1,去讨论now+1是否还存在now+1,同时用p记录本次取数(1~now)要到达的最右端
p
=
m
a
x
(
p
,
p
o
s
[
n
o
w
]
.
b
a
c
k
(
)
)
,
n
o
w
+
+
;
p=max(p,pos[now].back()),now++;
p=max(p,pos[now].back()),now++;。
②:如果没有该数字了,则将now加入b序列,同时将数字(1~now-1)中所有小于p位置的数去掉,这是本次使用过的,同时将now=0重新开始循环。
结束后要是now还有值,也需要加入b序列,应该取到最后没有数了,也没有将now置为0,即此时还在一个循环中。
最后一次循环的右端点后面还有多少数就加多少个0到b序列
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,a[N],num[N];
vector<int>ans;
vector<int>pos[N];
void solve()
scanf("%d",&n);
for(int i=1;i<=n;i++)
int x;scanf("%d",&x);
pos[x].push_back(i);
for(int i=0;i<=n;i++) reverse(pos[i].begin(),pos[i].end());
int now=0,p=0;
while(pos[0].size())
if(pos[now].size()) p=max(p,pos[now].back()),now++;
else
ans.push_back(now);
for(int i=0;i<now;i++)
while(pos[i].size()&&pos[i].back()<=p) pos[i].pop_back();
now=0;
if(now) ans.push_back(now);
for(int i=0;i<=n;i++)
while(pos[i].size()&&pos[i].back()<=p) pos[i].pop_back();
while(pos[i].size()) ans.push_back(0),pos[i].pop_back();
int len=ans.size();
printf("%d\\n",len);
for(int i=0;i<len;i++) printf("%d%c",ans[i],(i==len-1)?'\\n':' ');
ans.clear();
int main()
int t;scanf("%d",&t);
while(t--) solve();
D. Peculiar Movie Preferences
题意:在n个字符串中,按顺序选择一些字符串,能否构成回文串。
思路:每个字符串的长度<=3,所以拿map记录,暴力循环就行了。
可以的情况有
一个字符串:
①存在长度为1的字符串 (如a、b、c…)
②存在形如AA的字符串(如aa、bb、cc…)
③存在形如ABA或AAA的字符串(如aaa、aba、aca…)
两个字符串:
④2+2,即形如AB+BA(如ab+ba)
⑤2+3,即形如AB+CBA或AB+BBA(如ab+cba、ab+bba)
⑥3+2,即形如ABC+BA或ABB+BA(如abc+ba、abb+ba)
⑦3+3,即形如ABC+CBA或ABB+BBA(如abc+cba、abb+bba)
以上都不存在,则一定是没有了。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,flag;
string s[N];
map<string,int>mp;
void input()
flag=false,mp.clear();
cin>>n;
for(int i=1;i<=n;i++)
cin>>s[i];
int len=s[i].length();
if(len==1) flag=true; //单个字母
else if(len==2)
if(s[i][0]==s[i][1]) flag=true;//类似aa的形式
else
if(s[i][0]==s[i][2]) flag=true;//类似aba的形式
void solve()
input();
if(flag) puts("YES");return;
for(int i=1;i<=n;i++)
int len=s[i].length();
if(len==2)
string nows;
nows.push_back(s[i][1]);
nows.push_back(s[i][0]);
if(mp.find(nows)!=mp.end())puts("YES");return;
for(int j=0;j<26;j++)
string tes;
tes+=nows;
tes.push_back(j+'a');
if(mp.find(tes)!=mp.end())puts("YES");return;
mp[s[i]]=1;
else
string nows1;
nows1.push_back(s[i][2]);
nows1.push_back(s[i][1]);
nows1.push_back(s[i][0]);
if(mp.find(nows1)!=mp.end())puts("YES");return;
string nows2;
nows2.push_back(s[i][2]);
nows2.push_back(s[i][1]);
if(mp.find(nows2)!=mp.end())puts("YES");return;
mp[s[i]]=1;
puts("NO");
int main()
int t;cin>>t;
while(t--) solve();
E. Grid Xor
题意:给定一个n*n的矩阵,矩阵中点(i,j)的值为其四周的格子的异或值组成,要我们求所有格子的的数的异或值。保证n是偶数
思路:发现当某个点的四周都还未加入异或值时,选择该位置的数,就可以将四周没加入数加入异或值,发现在n为偶数时一定成立。(具体证明过程自证,我是画图找规律得出的)
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int n,a[N][N];
int dx[]=-1,1,0,0;
int dy[]=0,0,-1,1;
void solve()
scanf("%d",&n);
memset(a,0,sizeof(a));
int sum=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
int x;scanf("%d",&x);
bool flag=true;
for(int k=0;k<4;k++)
int nx=i+dx[k];
int ny=j+dy[k];
if(a[nx][ny]!=0)flag=false;break;
if(flag)
for(int k=0;k<4;k++)
int nx=i+dx[k];
int ny=j+dy[k];
a[nx][ny]=1;
sum^=x;
printf("%d\\n",sum);
int main()
int t;scanf("%d",&t);
while(t--) solve();
F1. Game on Sum (Easy Version)
题意:n轮游戏,每轮一个数,可以加上或减去,但至少加上的轮数要是m轮,每个数的范围为[0,k]的实数,问最终得分多少
思路:n的范围2000,可以
O
(
n
m
)
O(nm)
O(nm),
d
p
[
i
]
[
j
]
代
表
剩
下
i
轮
选
择
,
还
需
要
做
j
次
加
法
的
得
分
dp[i][j]代表剩下i轮选择,还需要做j次加法的得分
dp[i][j]代表剩下i轮选择,还需要做j次加法的得分
d
p
[
i
]
[
j
]
=
m
i
n
(
x
+
d
p
[
i
−
1
]
[
j
−
1
]
,
−
x
+
d
p
[
i
−
1
]
[
j
]
)
dp[i][j]=min(x+dp[i-1][j-1],-x+dp[i-1][j])
dp[i][j]=min(x+dp[i−1][j−1],−x+dp[i−Codeforces Round #767 (Div. 2) A ~ D
Codeforces Round #767 (Div. 2) ABCD题解
Codeforces Round #767 (Div. 2)(A B C D E F1 F2)
Codeforces Round #436 E. Fire(背包dp+输出路径)