Codeforces Round 113 简训

导语

第一次加训,思维量还是不够,许多细枝末节没有考虑清楚

涉及的知识点

贪心,思维,排列组合

链接:Codeforces Round 113

题目

A Balanced Substring

题目大意:给出一个只有a,b的字符串,找出该字符串的一个连续子串满足子串中a与b的数量相等

思路:直接找ab相连的地方

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int t,n;
char s[maxn],ch;
int main() {
    scanf("%d",&t);
    while(t--) {
        int l=0,r=0;
        scanf("%d",&n);
        scanf("%s",s+1);
        for(int i=1; i<n; i++)
            if(s[i]!=s[i+1]) {
                l=i,r=i+1;
                break;
            }
        if(l)
            printf("%d %d\n",l,r);
        else
            printf("-1 -1\n");
    }
    return 0;
}

B Chess Tournament

题目大意:略

思路:贪心的来想,让所有不想输的人与其他人的对局都为平局,让所有想至少赢一局的人都只赢一局,并且形成一个闭环,那么就要排除几种特殊情况,如果只有一或两个2类型的人,无解,只有一个,则不能赢别人,只有两个,比一场之后胜负已定,无法形成环

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn=51;
int t,n;
char s[maxn],maze[maxn][maxn];
int main() {
    scanf("%d",&t);
    while(t--) {
        scanf("%d",&n);
        scanf("%s",s+1);
        getchar();
        vector<int>one,two;
        memset(maze,0,sizeof(maze));
        for(int i=1; i<=n; i++) {
            if(s[i]=='1')
                one.push_back(i);
            else
                two.push_back(i);
            maze[i][i]='X';
        }
        if(two.size()==1||two.size()==2) {
            printf("NO\n");
            continue;
        }
        printf("YES\n");
        for(int i=0; i<one.size(); i++)
            for(int j=i+1; j<one.size(); j++)
                if(i!=j)
                    maze[one[i]][one[j]]=maze[one[j]][one[i]]='=';
        if(!two.empty()) {
            for(int i=0; i<two.size()-1; i++) {
                maze[two[i]][two[i+1]]='+';
                maze[two[i+1]][two[i]]='-';
            }
            maze[two[two.size()-1]][two[0]]='+';
            maze[two[0]][two[two.size()-1]]='-';
        }
        for(int i=1; i<=n; i++) {
            for(int j=1; j<=n; j++) {
                if(maze[i][j])putchar(maze[i][j]);
                else
                    putchar('=');
            }
            putchar('\n');
        }
    }
    return 0;
}

C Jury Meeting

题目大意:略

思路:很容易就能想到,能够持续输出的只可能是最大值,如果最大值的个数≥2,代表这两个同时拥有最大值的人可以交替输出,答案为n!,如果最大值只有1个,那么就要考虑次大值了,如果次大值为最大值-1,代表可以交替输出,且只有当所有次大值都在最大值前时才不符合题意,用插板法来思考,一共有次大值个数+1种情况,设次大值个数为num2,不符合题意的情况概率为1/(num2+1),答案为n!-n!/(num2+1),如果次大值小于最大值-1,代表无法控制最大值来交替输出,无解

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+10,mod=998244353;
ll t,n;
int main() {
    scanf("%lld",&t);
    while(t--) {
        ll maxx=0;
        unordered_map<ll,ll>a;
        scanf("%lld",&n);
        for(int i=1; i<=n; i++) {
            ll tmp;
            scanf("%lld",&tmp);
            maxx=max(maxx,tmp);
            a[tmp]++;
        }
        ll ans=1,sub=1;
        for(int i=1; i<=n; i++) {//预处理n!和n!-n!/(num2+1)
            ans=ans*i%mod;
            if(i!=a[maxx-1]+1)sub=sub*i%mod;
        }
        if(a[maxx]>=2)
            printf("%lld\n",ans);
        else if(a[maxx-1])
            printf("%lld\n",(ans-sub+mod)%mod);//防止出现负数
        else
            printf("0\n");
    }
    return 0;
}

参考文献

  1. Jury Meeting(思维+排列组合)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值