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;
}
1787

被折叠的 条评论
为什么被折叠?



