- CF1355D Game With Array
- CF1352D Alice, Bob and Candies
- CF1352F Binary String Reconstruction
- CF1352E Special Elements
- CF1364C Ehab and Prefix MEXs
- CF1361A Johnny and Contribution
- CF1365D Solve The Maze
1.CF1355D Game With Array
给出两个数 N N N, S S S
问是否可以找到一个序列和一个数 K K K( 0 < = K < = S 0<=K<=S 0<=K<=S)满足:存在一个长度为 N N N,和为 S S S序列,在其中找不到一个子段的和为 K K K或者 S − K S-K S−K
如果可以,输出YES以及找到的序列还有 K K K,否则,输出NO
首先手玩一下样例自己造几组数据可以发现,如果
2
∗
n
>
s
2*n>s
2∗n>s的话一定是无解的
然后构造一个除了最后一位之外全为1的数列即可
#include<bits/stdc++.h>
using namespace std;
int n,m,s;
const int maxn=1e5+5;
int a[maxn],b[maxn],c[maxn];
int main(){
cin>>n>>s;
if(2*n>s){
puts("NO");
return 0;
}
else{
puts("YES");
for(int i=1;i<=n-1;i++){
cout<<"1"<<" ";
}
cout<<s-n+1<<endl;
cout<<s/2;
}
return 0;
}
2.CF1352D Alice, Bob and Candies
一个很屑的模拟
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
int tt,n,m,a[maxn],b[maxn],num[maxn];
int main(){
cin>>tt;
while(tt--){
cin>>n;
int ans1=0,ans2=0,cnt=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
int i=0,j=n+1;
bool c=false;
int now1=0,now2=0;
while(i<j){
cnt++;
if(!c){
now1=0;
while(1){
i++;
now1+=a[i];
if(now1>now2)break;
}
if(i>=j){
while(i>=j){
now1-=a[i];
i--;
}
i++;
}
ans1+=now1;
}
else{
now2=0;
while(1){
j--;
now2+=a[j];
if(now2>now1)break;
}
if(i>=j){
while(j<=i){
now2-=a[j];
j++;
}
j--;
}
ans2+=now2;
}
c=!c;
if(i>=j-1)break;
}
printf("%d %d %d\n",cnt,ans1,ans2);
}
return 0;
}
3.CF1352F Binary String Reconstruction
每组数据有三个整数 n 0 , n 1 , n 2 n_0,n_1,n_2 n0,n1,n2。
你需要构造一个 01 01 01 串,长度为 n 0 + n 1 + n 2 + 1 n_0+n_1+n_2+1 n0+n1+n2+1,对于每一个长度为 2 2 2 的连续子串,总共有 n 0 n_0 n0 个和为 0 0 0, 有 n 1 n_1 n1 个和为 1 1 1,有 n 2 n_2 n2 个和为 2 2 2。
保证输入有解,对于每一组数据,输出一行,为一个 01 01 01 串,没有空格,如果有多组解,输出任意一个即可。
先输出 a + 1 a+1 a+1个0,再输出 c + 1 c+1 c+1个1,最后输出长度为 b − 1 b-1 b−1的01串即可
#include<bits/stdc++.h>
using namespace std;
int t;
int a,b,c;
int main(){
cin>>t;
while(t--){
cin>>a>>b>>c;
int n=a+b+c+1;
if(a==0&&b==0){
for(int i=1;i<=n;i++){
printf("1");
}
cout<<endl;
continue;
}
if(b==0&&c==0){
for(int i=1;i<=n;i++){
printf("0");
}
cout<<endl;
continue;
}
int ans1,ans2,ans3;
for(int i=1;i<=a+1;i++){
printf("0");
}
for(int i=1;i<=c+1;i++){
printf("1");
}
for(int i=1;i<=b-1;i++){
if(i%2==1)printf("0");
else printf("1");
}
cout<<endl;
}
return 0;
}
4.CF1352E Special Elements
The first line contains an integer t t t ( 1 ≤ t ≤ 1000 1 \le t \le 1000 1≤t≤1000 ) — the number of test cases in the input. Then t t t test cases follow.
Each test case is given in two lines. The first line contains an integer $ n $ ( $ 1 \le n \le 8000 $ ) — the length of the array a a a . The second line contains integers a 1 , a 2 , … , a n a_1, a_2, \dots, a_n a1,a2,…,an ( 1 ≤ a i ≤ n 1 \le a_i \le n 1≤ai≤n ).
It is guaranteed that the sum of the values of $ n $ for all test cases in the input does not exceed 8000 8000 8000
给你a数列,让你判断其中的每个元素是否能写成数列中几个连续元素之和,并统计个数。
暴力枚举求后缀和,超过n就break
#include<bits/stdc++.h>
using namespace std;
int t,n,m;
int a[8005],sum[8005];
int dd[8005];
signed main(){
cin>>t;
while(t--){
cin>>n;
memset(dd,0,sizeof(dd));
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
for(int i=1;i<=n-1;i++){
sum[i]=a[i];
for(int j=i+1;j<=n;j++){
sum[j]=sum[j-1]+a[j];
if(sum[j]>n)break;
dd[sum[j]]=1;
}
}
int ans=0;
for(int i=1;i<=n;i++){
if(dd[a[i]]==1)ans++;
}
printf("%d\n",ans);
}
return 0;
}
5.CF1364C Ehab and Prefix MEXs
给出一个长度为 n n n 的序列 A A A,你需要找到一个长度为 n n n 的序列 B B B,满足 A i = m e x ( { B 1 , B 2 , … , B n } ) A_i=mex(\{B_1,B_2,\dots,B_n\}) Ai=mex({B1,B2,…,Bn})。
其中 m e x mex mex 函数的结果是最小的未出现在集合中的非负整数
如果 i > 1 , a [ i − 1 ] < a [ i ] i>1,a[i-1]<a[i] i>1,a[i−1]<a[i]就把这个数填上,如样例3,输入为 1 , 1 , 3 1,1,3 1,1,3, i = 1 i=1 i=1时候,输出 0 0 0, f = 1 f=1 f=1,i=2,输出 f = 2 f=2 f=2, f + + f++ f++变为 2 2 2,当 i = 3 i=3 i=3, a [ 2 ] < a [ 3 ] a[2]<a[3] a[2]<a[3],此时必须填入 a [ 2 ] a[2] a[2],因为 a [ 2 ] a[2] a[2]是前一组中不存在的最小数字,不填上它的话就不可能让这个 m e x mex mex变成 a [ 3 ] a[3] a[3]
#include<bits/stdc++.h>
using namespace std;
int n,m,t;
const int maxn=1e5+5;
int a[maxn],b[maxn],c[maxn];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
c[a[i]]=1;
}
int f=0;
for(int i=1;i<=n;i++){
if(i>1&&a[i-1]<a[i]){
cout<<a[i-1]<<" ";
}
else{
while(c[f]){
f++;
}
cout<<f++<<" ";
}
}
return 0;
}
6.CF1361A Johnny and Contribution
咕了,待补
7.CF1365D Solve The Maze
要封住每一个坏人,问是否所有好人都能到达终点
先将坏人边上的路变成墙,再从终点
d
f
s
dfs
dfs看遇到的好人数量是否为总数即可
需要特判终点不可到达并且好人数量不为
0
0
0的情况
#include<bits/stdc++.h>
using namespace std;
int n,m,t;
const int dx[]={1,-1,0,0};
const int dy[]={0,0,-1,1};
char a[55][55];
int mz[55][55];
int vis[55][55];
int ans=0;
int flag=0;
void dfs(int x,int y){
vis[x][y]=1;
if(a[x][y]=='G')ans++;
for(int i=0;i<4;i++){
int xx=dx[i]+x;
int yy=dy[i]+y;
if(vis[xx][yy]==0&&mz[xx][yy]!=1&&xx>=1&&yy>=1&&xx<=n&&yy<=m){
dfs(xx,yy);
}
}
return;
}
signed main(){
cin>>t;
while(t--){
int kk=0;
memset(vis,0,sizeof vis);
memset(mz,0,sizeof mz);
ans=0;
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
if(a[i][j]=='#'){
mz[i][j]=1;
}
if(a[i][j]=='G'){
kk++;
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]=='B'){
mz[i-1][j]=mz[i+1][j]=mz[i][j+1]=mz[i][j-1]=1;
}
}
}
if(mz[n][m]==1&&kk!=0){
printf("NO\n");
continue;
}
dfs(n,m);
if(ans==kk)printf("YES\n");
else printf("NO\n");
}
return 0;
}