感觉这场比赛题目质量挺高(A 全场最佳),难度也不小。虽然 unr 后就懒得打了。

A. Inscribed Figures

题意

给你若干个图形,每个图形为三角形、圆形或正方形,第 \(i\) 个图形内接于第 \(i-1\) 个图形。问交点是否有限,如有限求交点个数。

(题目还有很多细节,具体见原题。)

题解

如果两个一样的图形相邻或正方形和三角形相邻。

圆和三角形有 \(3\) 个交点,和正方形有 \(4\) 个交点。

注意如果是 【圆、正方形、三角形】这样的,最上面有一个交点会重合,答案要减 1 。(出题人一开始也没注意到,后来重测导致unr)。

总体来说,这题真的没什么意思……

code

#include<bits/stdc++.h>
using namespace std;
int a[233];
int main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
int n; scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
int ans=0,l=a[1];
for(int i=2;i<=n;++i)
{
int x=a[i];
if(x==l)
{
printf("Infinite");
return 0;
}
int t=x;
if(x>l) x=l,l=t;
if(x==1) ans+=l+1;
if(x==2) {
printf("Infinite");
return 0;
}
l=t;
}
for(int i=3;i<=n;++i) if(a[i-2]==3&&a[i-1]==1&&a[i]==2) --ans;
printf("Finite\n%d",ans);
}

B. Ugly Pairs

题意

给你一个字符串 \(S\) ,重排该字符串使得任意两个在字母表中相邻的字符在字符串中不相邻。若无解输出 No answer .

\(T\) 组数据。 \(T,|S| \le 100\) 。

题解

去重,只考虑字符的可重集。设 \(n\) 为去重后集合大小。

容易发现 \(n\le 3\) 时会出现无解。

我们可以考虑构造。有很多种构造方案可以解决。对于 \(n > 4\) ,一种构造方案是每次选 \(i\) 和 \(i+n/2\) 放在一起。

那么对于 \(n\le 4\) ,我们可以采用手玩或爆搜来解决。

code

#include<bits/stdc++.h>
using namespace std;
const int N=105;
char s[N]; bool flag,vis[30];
int n,m,num[30],ans[N];
void dfs(int u, int now)
{
if(flag) return ;
if(now>n)
{
flag=true;
for(int i=1;i<=n;++i)
while(num[ans[i]]--) putchar(ans[i]+'a');
puts("");
return ;
}
for(int i=0;i<26;++i)
{
if(!vis[i]&&num[i]&&i+1!=u&&i-1!=u)
{
vis[i]=true;
ans[now]=i;
dfs(i,now+1);
vis[i]=false;
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("b.in","r",stdin);
#endif
int T; scanf("%d",&T);
while(T--)
{
flag=false;
scanf("%s",s+1);
n=strlen(s+1);
memset(num,0,sizeof(num));
memset(vis,false,sizeof(vis));
for(int i=1;i<=n;++i) ++num[s[i]-'a'];
sort(s+1,s+1+n);
n=unique(s+1,s+1+n)-s-1;
if(n<=4)
{
dfs(233,1);
if(!flag) puts("No answer");
continue;
}
for(int i=1;i<=n>>1;++i)
{
while(num[s[i]-'a']--) putchar(s[i]);
while(num[s[i+(n-1)/2+1]-'a']--) putchar(s[i+(n-1)/2+1]);
}
if(n&1) while(num[s[n/2+1]-'a']--) putchar(s[n/2+1]);
puts("");
}
}

C. Match Points

题意

给你 \(n\) 个点 \(x_1,x_2,...,x_n\) 。两个点 \(i,j\) 能配对当且仅当 \(|x_i-x_j|\ge z\) 。求最大配对数量。

\(n\le 2\cdot 10^5, x_i,z\le 10^9\) 。

题解

首先直接顺次匹配肯定是错的,就不解释了。

考虑二分答案 \(y\) 。我们只要考虑前 \(y\) 个数,判断 \(x_i\) 能否和 \(x_{n-y+i}\) 匹配即可。

由这个二分答案的做法,我们可以进一步得出一个线性做法:我们可以把原序列分成两半然后顺次匹配,用双指针做一下就行了。

code

#include<bits/stdc++.h>
using namespace std;
inline int gi()
{
char c; int x=0,f=1;
for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+c-'0';
return x*f;
}
const int N=2e5+5;
int a[N],n,z,ans;
int main()
{
#ifndef ONLINE_JUDGE
freopen("c.in","r",stdin);
#endif
n=gi(),z=gi();
for(int i=1;i<=n;++i) a[i]=gi();
sort(a+1,a+1+n);
int l=1,r=n/2+1;
while(l<=r&&l<=n/2&&r<=n)
{
if(a[r]-a[l]>=z) ++ans,++l;
++r;
}
printf("%d",ans);
}

D. 0-1-Tree

题意

给你一棵 \(n\) 个点的树,每条边标有 0 或 1 。问有多少对点 \((x,y)\) 满足 \(x\rightarrow y\) 的路径上 0 边不会在 1 边之后出现。

\(n\le 2\cdot 10^5\) 。

题解

先经过 0 边再经过 1 边。考虑枚举分界点,贡献即为 仅通过 0 边与其连通的节点数 * 仅通过 1 边与其连通的节点数。并查集维护即可。

code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int gi()
{
char c; int x=0,f=1;
for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+c-'0';
return x*f;
}
const int N=200005;
int f[2][N],s[2][N];
int findset(int u, int w)
{
if(f[w][u]==u) return u;
return f[w][u]=findset(f[w][u],w);
}
void unionset(int u, int v, int w)
{
int fu=findset(u,w),fv=findset(v,w);
s[w][fu]+=s[w][fv];
f[w][fv]=fu;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("d.in","r",stdin);
#endif
int n=gi();
for(int i=0;i<2;++i)
for(int j=1;j<=n;++j) f[i][j]=j,s[i][j]=1;
for(int i=1;i<n;++i)
{
int u=gi(),v=gi(),w=gi();
unionset(u,v,w);
}
long long ans=0;
for(int i=1;i<=n;++i)
ans+=1ll*s[0][findset(i,0)]*s[1][findset(i,1)];
printf("%I64d",ans-n);
}

E. Special Segments of Permutation

题意

给你一个长度为 \(n\) 的排列 \(p\) ,询问有多少个区间 \([l,r]\) ,满足 \(\displaystyle p_l+p_r=\max_{i=l}^r p_i\) 。

\(n\le 2\cdot 10^5\)

题解

考虑最大值分治。对于区间 \([l,r]\) ,rmq 找到最大值 \(m\) ,我们选择 \([l,m-1]\) 和 \([m+1,r]\) 中长度最小的区间来枚举边界点。然后递归 \([l,m-1]\) 和 \([m+1,r]\) 。这样是启发式合并的复杂度 ,是 \(O(n\log n)\) 的 。

code

#include<bits/stdc++.h>
using namespace std;
inline int gi()
{
char c; int x=0,f=1;
for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+c-'0';
return x*f;
}
const int N=2e5+5;
int f[N][30],p[N],pos[N],lg[N],ans,n;
inline int chmax(int x, int y) {
return p[x]>p[y]?x:y;
}
inline int getmx(int l, int r)
{
int t=lg[r-l+1];
return chmax(f[l][t],f[r-(1<<t)+1][t]);
}
void solve(int l, int r)
{
if(l>=r) return ;
int m=getmx(l,r);
if(m-l<r-m)
for(int i=l;i<m;++i)
ans+=(m<=pos[p[m]-p[i]]&&pos[p[m]-p[i]]<=r);
else
for(int i=m+1;i<=r;++i)
ans+=(l<=pos[p[m]-p[i]]&&pos[p[m]-p[i]]<=m);
solve(l,m-1),solve(m+1,r);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("e.in","r",stdin);
#endif
n=gi();
for(int i=2;i<=n;++i) lg[i]=lg[i-1]+!(i&(i-1));
for(int i=1;i<=n;++i) p[i]=gi(),pos[p[i]]=f[i][0]=i;
for(int j=1;(1<<j)<=n;++j)
for(int i=1;i+(1<<j)-1<=n;++i)
f[i][j]=chmax(f[i][j-1],f[i+(1<<j-1)][j-1]);
solve(1,n);
printf("%d",ans);
}

F. Card Bag

题意

你在玩游戏。给你 \(n\) 张牌,每张牌上有个数字 。你每次从中等概率选出一张牌并扔掉。设你选出的数为 \(x\) ,上一次选出的数为 \(y\) 。若 \(x>y\) 你输, \(x=y\) 你赢, \(x<y\) 继续。若牌扔完后游戏仍未结束则你输。求你赢的概率。

题解

我们需要选出一条单升序列,最后再选上序列中的最后一个数。

首先我们记下每个数字出现的次数,然后对原序列排序去重。

设 \(f(i,j)\) 表示前 \(i\) 个数选了 \(j\) 个的概率。

\(f(i,j)=f(i-1,j)+f(i-1,j-1)\times \frac{x_i}{n-j+1}\)

其中 \(x_i\) 表示这个数出现的个数。

统计答案的话在中间做一下就行了。

code

#include<bits/stdc++.h>
using namespace std;
inline int gi()
{
char c; int x=0,f=1;
for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+c-'0';
return x*f;
}
const int N=5005,Mod=998244353;
int f[N][N],inv[N],num[N],a[N],n,m,ans;
int main()
{
#ifndef ONLINE_JUDGE
freopen("f.in","r",stdin);
#endif
n=m=gi();
for(int i=1;i<=n;++i) a[i]=gi(),++num[a[i]];
inv[0]=inv[1]=1;
for(int i=2;i<=n;++i) inv[i]=1ll*(Mod-Mod/i)*inv[Mod%i]%Mod;
sort(a+1,a+1+n);
n=unique(a+1,a+1+n)-a-1;
f[0][0]=1;
for(int i=1;i<=n;++i)
for(int j=0;j<=i;++j)
{
f[i][j]=1ll*num[a[i]]*inv[m-j+1]%Mod*f[i-1][j-1]%Mod;
ans=(ans+1ll*(num[a[i]]-1)*inv[m-j]%Mod*f[i][j]%Mod)%Mod;
f[i][j]=(f[i][j]+f[i-1][j])%Mod;
}
printf("%d",ans);
}

Educational Codeforces Round 64 选做的更多相关文章

  1. Educational Codeforces Round 65 选做

    好久没更博客了,随便水一篇 E. Range Deleting 题意 给你一个长度为 \(n\) 的序列 \(a_1,a_2,\dots a_n\) ,定义 \(f(l,r)\) 为删除 \(l\le ...

  2. Educational Codeforces Round 63 选做

    D. Beautiful Array 题意 给你一个长度为 \(n\) 的序列.你可以选择至多一个子段,将该子段所有数乘上给定常数 \(x\) .求操作后最大的最大子段和. 题解 考虑最大子段和的子段 ...

  3. Educational Codeforces Round 64 (Rated for Div. 2)题解

    Educational Codeforces Round 64 (Rated for Div. 2)题解 题目链接 A. Inscribed Figures 水题,但是坑了很多人.需要注意以下就是正方 ...

  4. Educational Codeforces Round 64(ECR64)

    Educational Codeforces Round 64 CodeForces 1156A 题意:1代表圆,2代表正三角形,3代表正方形.给一个只含1,2,3的数列a,ai+1内接在ai内,求总 ...

  5. Educational Codeforces Round 64 部分题解

    Educational Codeforces Round 64 部分题解 不更了不更了 CF1156D 0-1-Tree 有一棵树,边权都是0或1.定义点对\(x,y(x\neq y)\)合法当且仅当 ...

  6. Educational Codeforces Round 64部分题解

    Educational Codeforces Round 64部分题解 A 题目大意:给定三角形(高等于低的等腰),正方形,圆,在满足其高,边长,半径最大(保证在上一个图形的内部)的前提下. 判断交点 ...

  7. Educational Codeforces Round 64 (Rated for Div. 2) (线段树二分)

    题目:http://codeforces.com/contest/1156/problem/E 题意:给你1-n  n个数,然后求有多少个区间[l,r] 满足    a[l]+a[r]=max([l, ...

  8. Educational Codeforces Round 64 (Rated for Div. 2) A,B,C,D,E,F

    比赛链接: https://codeforces.com/contest/1156 A. Inscribed Figures 题意: 给出$n(2\leq n\leq 100)$个数,只含有1,2,3 ...

  9. Educational Codeforces Round 64 -C(二分)

    题目链接:https://codeforces.com/contest/1156/problem/C 题意:给出n个数和整形数z,定义一对数为差>=z的数,且每个数最多和一个数组成对,求最多有多 ...

随机推荐

  1. mysql cmmand not found

    https://www.cnblogs.com/yangzigege/p/8337393.html

  2. AT2827 最长上升子序列LIS(nlogn的DP优化)

      题意翻译 给定一长度为n的数列,请在不改变原数列顺序的前提下,从中随机的取出一定数量的整数,并使这些整数构成单调上升序列. 输出这类单调上升序列的最大长度. 数据范围:1<=n<=10 ...

  3. bash脚本编程

    一.bash中的变量 变量类型: 本地变量:只对当前shell进程有效,对其子shell以及其它shell都无效;   定义变量:[set]Var_name="value" 变量赋 ...

  4. Codeforces 1260 ABC

    DEF 题对于 wyh 来说过于毒瘤,十分不可做. A. Heating Description: 给定\(a,b\),将\(b\)分成至少\(a\)个正整数,使这些正整数的平方和最小. Soluti ...

  5. 使用 C++ 处理 JSON 数据交换格式

    一.摘要 JSON 的全称为:JavaScript Object Notation,顾名思义,JSON 是用于标记 Javascript 对象的,JSON 官方的解释为:JSON 是一种轻量级的数据传 ...

  6. SQL数据库入门基础

      SQL(Structure Query Language,结构化查询语言)语言是国际标准化组织(ISO)采纳的标准数据库语言. 数据库就是一幢大楼,我们要先盖楼,然后再招住户(住户当然就是数据库对 ...

  7. JS 循环赋值

    var x_world_map_tiles = 100; var y_world_map_tiles = 100; var world_map_array = []; for (i=0; i<= ...

  8. OOP的四大特征

    抽象 abstract 最近对抽象有些不熟悉,那么先谈谈抽象. 抽象在java中常常表现为抽象类和抽象方法,即被abstract关键字修饰的类和方法. 抽象类:被abstract修饰的类 1 和接口不 ...

  9. SSH和screen服务

    SSH是一种能够以安全的方式提供远程登录的协议,目前远程管理的首选方式,sshd是基于SSH协议开发的一款远程管理服务程序,在Linux系统中需要部署sshd服务程序才能使用SSH协议来进行远程管理, ...

  10. Python学习第九课——匿名函数

    匿名函数 # 匿名函数 func = lambda x: x + 1 # x表示参数 x+1表示处理逻辑 print(func(10)) # 输出结果为11 # 例:如何将name="han ...