Codeforces Global Round 4 题解

技不如人,肝败吓疯……

开场差点被 A 题意杀了,幸好仔细再仔细看,终于在第 7 分钟过掉了。

跟榜。wtf 怎么一群人跳题/倒序开题?

立刻紧张,把 BC 迅速切掉,翻到了 100+。

开 D。感觉有点吓人……感觉有点可做?

的确挺可做。再切掉 D,但是此时已经到 300+ 了。

没事,还能翻。

开 E。这……什么玩意?

瞄了一眼 F1,……

盯着这两题盯到自闭。

最后 rk 1000 左右。我的名字颜色真的是对的吗……


A

看懂题了就是水题。选上所有小于等于第一个党派一半人数的党派,如果不行就不行,否则就可以。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=100010;
#define MP make_pair
#define PB push_back
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline ll read(){
    char ch=getchar();ll x=0,f=0;
    while(ch<‘0‘ || ch>‘9‘) f|=ch==‘-‘,ch=getchar();
    while(ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
    return f?-x:x;
}
int n,a[maxn],s,s2,cnt;
int main(){
    n=read();
    FOR(i,1,n) s+=a[i]=read();
    s2=a[1];cnt=1;
    FOR(i,2,n) if(a[1]>=2*a[i]) s2+=a[i],cnt++;
    if(s2*2<=s) puts("0");
    else{
        printf("%d\n",cnt);
        printf("1 ");
        FOR(i,2,n) if(a[1]>=2*a[i]) printf("%d ",i);
    }
}


B

枚举中间的 o,然后看看两边能选出多少个 vv,简单前缀/后缀和解决。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=1000100;
#define MP make_pair
#define PB push_back
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline ll read(){
    char ch=getchar();ll x=0,f=0;
    while(ch<‘0‘ || ch>‘9‘) f|=ch==‘-‘,ch=getchar();
    while(ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
    return f?-x:x;
}
int n,pre[maxn],suf[maxn];
ll ans;
char s[maxn];
int main(){
    scanf("%s",s+1);
    n=strlen(s+1);
    FOR(i,2,n){
        pre[i]=pre[i-1];
        if(s[i]==‘v‘ && s[i-1]==‘v‘) pre[i]++;
    }
    ROF(i,n-1,1){
        suf[i]=suf[i+1];
        if(s[i]==‘v‘ && s[i+1]==‘v‘) suf[i]++;
    }
    FOR(i,1,n) if(s[i]==‘o‘) ans+=1ll*pre[i-1]*suf[i+1];
    cout<<ans<<endl;
}


C

最左上角的可以随便选。

第一行的在左边那个已经确定后,可以发现可以选两种。

第一列的同理,每个可以选两种。

不在第一行也不在第一列的,发现只能选固定的一种。

答案就是 $2^{n+m}$。

(为什么一群人盯样例盯出来了……)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=1010,mod=998244353;
#define MP make_pair
#define PB push_back
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline ll read(){
    char ch=getchar();ll x=0,f=0;
    while(ch<‘0‘ || ch>‘9‘) f|=ch==‘-‘,ch=getchar();
    while(ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
    return f?-x:x;
}
int n,m;
int qpow(int a,int b){
    int ans=1;
    for(;b;b>>=1,a=1ll*a*a%mod) if(b&1) ans=1ll*ans*a%mod;
    return ans;
}
int main(){
    n=read();m=read();
    printf("%d\n",qpow(2,n+m));
}


D

每个点度数不小于 $2$,所以边数最小为 $n$。

不妨找到第一个大于等于 $n$ 的质数作为边数。

根据一些%*#(!^定理(猜想?),$n\ge 3$ 时,$[n,\frac{3}{2}n]$ 中至少有一个质数。

可以通过下面这个方法构造出一个有 $2n-m$ 个度数为 $2$ 的点,$m-n$ 个度数为 $3$ 的点的图。

首先 $i$ 向 $i+1$ 连边($n$ 向 $1$ 连边),此时用了 $n$ 条边,所有点度数为 $2$。

剩下的 $m-n$ 条边随便连,只要没有重边并且这 $m-n$ 条边不重复用点就好了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=100010;
#define MP make_pair
#define PB push_back
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline ll read(){
    char ch=getchar();ll x=0,f=0;
    while(ch<‘0‘ || ch>‘9‘) f|=ch==‘-‘,ch=getchar();
    while(ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
    return f?-x:x;
}
int n,m,cnt;
bool use[maxn];
bool check(int x){
    if(x==1) return false;
    for(int i=2;i*i<=x;i++) if(x%i==0) return false;
    return true;
}
int main(){
    n=m=read();
    while(!check(m)) m++;
    cnt=m-n;
    printf("%d\n",m);
    FOR(i,1,n){
        printf("%d %d\n",i,i%n+1);
        if(cnt && !use[i]){
            int to=i%n+1;
            to=to%n+1;
            while(use[to]) to=to%n+1;
            use[i]=use[to]=true;
            printf("%d %d\n",i,to);
            cnt--;
        }
    }
}


E

这也太神了吧……

对于长度 $\le 3$ 的字符串,可以任意选其中一个字符。

对于长度 $\ge 4$ 的字符串,取出前两个字符和后两个字符,由于相邻字符不相等,所以一定可以从前两个中选出一个,后两个中选出一个,使得它们相等。删掉这四个字符,然后重复操作。

可以发现这样求出的一定是回文串而且合法。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=1000100;
#define MP make_pair
#define PB push_back
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline ll read(){
    char ch=getchar();ll x=0,f=0;
    while(ch<‘0‘ || ch>‘9‘) f|=ch==‘-‘,ch=getchar();
    while(ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
    return f?-x:x;
}
int n,m,l,r;
char s[maxn],t[maxn];
int main(){
    scanf("%s",s+1);
    n=strlen(s+1);
    l=1;r=n;
    while(r-l+1>=4){
        if(s[l]==s[r] || s[l]==s[r-1]) t[++m]=s[l];
        else t[++m]=s[l+1];
        l+=2;r-=2;
    }
    FOR(i,1,m) putchar(t[i]);
    if(l<=r) t[++m]=s[l];
    ROF(i,m,1) putchar(t[i]);
}

原文地址:https://www.cnblogs.com/1000Suns/p/11220815.html

时间: 2024-08-25 21:50:35

Codeforces Global Round 4 题解的相关文章

codeforces global round 1题解搬运

A,B很简单,跳过了. C题规律相当明显,可以直接对\(2^n-1\)打表,也可以不打表直接算最大因数. D题两种操作转化一下DP即可. E题考虑查分数组不变的性质. F题考虑dfs时动态维护每个叶子的深度,从一个节点走向它的孩子相当于孩子对应的区间加,不包含孩子的区间减. #include <bits/stdc++.h> using namespace std; typedef long long ll; const int P=1050000; const int N=500010; in

Codeforces Global Round 3 题解

A 送分题 B 送分题 C 考虑先依次把\(2\sim n-1\)换到正确的位置,这个只要利用\(1,n\)两个位置交换就行了. 然后如果\(n\)在第一位就交换\(1,n\). D 显然\(a<b\)和\(a>b\)的可以分别考虑.不失一般性考虑\(a<b\)的.那么相当于要选出若干二元组并排序,要求满足\(b_i>a_{i+1}\).考虑对数值建点,\(a\)向\(b\)连边,所有\(i\)向\(i-1\)连边,相当于要走一条路径经过最多\(a->b\)的边.这样可以直观

Codeforces Global Round 7 题解

A 一种合法构造方式是\(299\cdots 9\) code B 发现每次的\(x_{i-1}\)都是知道的,于是可以直接递推. code C 最终答案所选的数一定是\(n-k+1\)到\(n\)的所有数.把这些数所在的位置记作\(p_1,p_2,\cdots,p_k\). 不难发现每个\(r_i\in [p_i,p_{i+1})\),于是答案就是\(\prod (p_{i+1}-p_i)\). code D 首先把首尾能构成回文的部分删掉,因为这部分一定会出现在答案中. 问题变成了在当前字符

Codeforces Global Round 1 (A-E题解)

Codeforces Global Round 1 题目链接:https://codeforces.com/contest/1110 A. Parity 题意: 给出{ak},b,k,判断a1*b^(k-1)+a2*b^(k-2)+...+ak*b^0的奇偶性. 题解: 暴力求模2意义下的值就好了. 代码如下: #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 2e5+5; int

【手抖康复训练1 】Codeforces Global Round 6

[手抖康复训练1 ]Codeforces Global Round 6 总结:不想复习随意打的一场,比赛开始就是熟悉的N分钟进不去时间,2333,太久没写题的后果就是:A 题手抖过不了样例 B题秒出思路手抖过不了样例,C题秒出思路手抖过不了样例*3 D题 手抖 过的了样例 ,调了1h,赛后发现变量名写错了,改一个字符就能AC... 题目等补完题一起放上来QAQ 原文地址:https://www.cnblogs.com/ttttttttrx/p/12110199.html

Codeforces Global Round 7【ABCD】(题解)

目录 涵盖知识点:思维.构造.马拉车. 比赛链接:传送门 D题只有数据范围的区别,故只写D2. 好多题啊,随缘更新.(其实懒得写) A - Bad Ugly Numbers B - Maximums C - Permutation Partitions D2 - Prefix-Suffix Palindrome (Hard version) 涵盖知识点:思维.构造.马拉车. 比赛链接:传送门 D题只有数据范围的区别,故只写D2. 好多题啊,随缘更新.(其实懒得写) A - Bad Ugly Nu

Codeforces Global Round 5 部分题解

tourist的劲题,掉了17分,着实心痛,本来是有分可恰到的 A.给你一个数列\(a\),你需要构造一个数列\(b\),使得每一个\(b\)都等于\(a/2\),向上或向下取整由你决定 并且还要使得\(\sigma b\)的总和等于0 数据是保证有解的 那么我们就令所有\(b\)等于\(\lfloor a/2 \rfloor\),求出总和 再遍历一遍数组,sum过大则把某些负数调整为向上取整,否则把正数调整 代码: #include <bits/stdc++.h> #define int l

【 Codeforces Global Round 1 B】Tape

[链接] 我是链接,点我呀:) [题意] x轴上有m个连续的点,从1标号到m. 其中有n个点是特殊点. 让你用k段区间将这n个点覆盖. 要求区间的总长度最小. [题解] 一开始假设我们需要n个胶带(即包含每一个点) 然后因为k<=n 所以可能胶带不够用. 那么就得一个胶带跨过两个点. 怎么选择最好呢? 可以把b[i]-b[i-1]-1处理出来排个序. (优先取较小的花费) 然后取前n-k个累加和sum. 因为每取一个就少用一段胶带. 然后sum+n就是答案了 [代码] import java.i

【Codeforces Global Round 1 C】Meaningless Operations

[链接] 我是链接,点我呀:) [题意] 给你一个a 让你从1..a-1的范围中选择一个b 使得gcd(a^b,a&b)的值最大 [题解] 显然如果a的二进制中有0的话. 那么我们就让选择的b的二进制中对应的位置为1 剩下全为0就好 这样a的二进制全都变成1之后就是答案了(gcd的右边是0). 但是如果a的二进制里面全是1的话. 就没办法这么构造了 这里有两种情况. ①.1的个数是偶数 那么就101010这样构造 另外一个数就是010101 答案就是010101转换成十进制 ②.1的个数是奇数