感觉这场比赛题目质量挺高(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. 算法复杂度图示&JavaScript算法链接

    https://juejin.im/post/5c9a1d58e51d4559bb5c6694

  2. Servlet 学习(四)

    HTTP 响应的构成1.HTTP 响应行: 协议.状态.描述 HTTP 1.1 中定义的状态代码 100-199 是信息性代码,标示客户应该采取的其它动作 200-299 表示请求成功 300-399 ...

  3. 洛谷P1198 [JSOI2008]最大数(线段树)

    题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制:LLL不超过当前数列的长度.(L> ...

  4. springboot之快速创建项目

    1.选择创建新项目: 2.选择spring initializr,然后next 3.填写项目元数据,然后next 4.选择项目依赖,然后next 5.点击finish,完成项目创建

  5. R语言 sample抽样函数

    Sample 函数用法: sample(x, size, replace = FALSE, prob = NULL) Arguments x - 可以是含有一个或多个元素的向量或只是一个正整数.x的长 ...

  6. 洗牌函数[打乱数组的顺序] slice()的新运用 [原来arr.slice(start, end) 的start不是必需的]

    function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1) + min) } functio ...

  7. 记录—JPA生成数据库表

    环境 springBoot+JPA+MySQL application-dev.yml 注意:配置中的blog数据库需要先创建,否则启动springBoot会报错 spring: #数据库连接配置 d ...

  8. UniGUI之提示信息MessageDlg及获得信息Prompt(15)

    UniGui的信息弹出框MessageDlg的原型定义如下: procedure MessageDlg(const Msg: string; DlgType: TMsgDlgType; Buttons ...

  9. Scrapy 中的模拟登陆

    目前,大部分网站都具有用户登陆功能,其中某些网站只有在用户登陆后才能获得有价值的信息,在爬取这类网站时,Scrapy 爬虫程序先模拟登陆,再爬取内容 1.登陆实质 其核心是想服务器发送含有登陆表单数据 ...

  10. change事件和input事件的区别

    input事件: input事件在输入框输入的时候回实时响应并触发 change事件: change事件在input失去焦点才会考虑触发,它的缺点是无法实时响应.与blur事件有着相似的功能,但与bl ...