Educational Codeforces Round 64

CodeForces 1156A

题意:1代表圆,2代表正三角形,3代表正方形。给一个只含1,2,3的数列a,ai+1内接在ai内,求总共有多少个交点。

交了好多遍才过。分类讨论一下内接的情况,然后注意到当正方形内接圆形再内接三角形时会有一个点重复,减去即可。

code

#include<cstdio>
int n,fig[],ans,flag,haha[][];
int main()
{
scanf("%d",&n);
haha[][]=;haha[][]=;
haha[][]=;haha[][]=;
haha[][]=;haha[][]=;
for(int i=;i<=n;i++)
{
scanf("%d",&fig[i]);
ans+=haha[fig[i-]][fig[i]];
if(fig[i]==&&fig[i-]==&&fig[i-]==)ans--;
if(ans>=)
{
printf("Infinite\n");
return ;
}
}
printf("Finite\n");
printf("%d",ans);
}

CodeForces 1156B

题意:给一个字符串,要求重新排列后不能有字母表中相邻的字母被放在一起(如“ab”与“ba”就不合法)。若可以做到就输出字符串,反之输出“No answer”。

相同的字母可以缩成一个。发现只有当给的字母是两个或三个相邻的字母时是无法做到的(“ab”,“abc”),特判处理。对所有的字母排序后就可以乱搞了。

当总共有奇数个字母时,将a(1+n)/2拿出来放到答案中的第一个,剩下的就按a1,an,a2,an-1......这样来排。

(总共有3个字母时可能第一个或最后一个与中间的那个相邻,特判处理一下)

当总共有偶数个字母时,将a(1+n)/2+1放到答案中的第一个,a1放到答案中的第二个,an放到答案的第三个,a(1+n)/2放到答案的第四个,剩下的就按an-1,a2,an-2,a3....这样来排。

(一开始还想用哈密顿回路来做)

code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int T,cha[],tot,tim[],ans[];
char ch[];
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%s",ch+);
int len=strlen(ch+);
for(int i=;i<=len;i++)
{
if(!tim[ch[i]-'a'])
cha[++tot]=ch[i]-'a';
tim[ch[i]-'a']++;
}
sort(cha+,cha++tot);
if((tot==&&cha[]+==cha[]&&cha[]+==cha[])||(tot==&&cha[]+==cha[]))
printf("No answer\n");
else
{
if(tot%==)
{
int mid1=tot/,mid2=mid1+;
ans[]=cha[mid2];ans[]=cha[];
ans[]=cha[tot];ans[]=cha[mid1];
int l=;
for(int i=;i<mid1;i++)
ans[++l]=cha[tot-i+],ans[++l]=cha[i];
}
else
{
ans[]=cha[tot/+];
if(tot!=||(tot==&&cha[]+!=cha[]&&cha[]+!=cha[]))
for(int i=;i<=tot/;i++)
ans[i*]=cha[i],ans[i*+]=cha[tot-i+];
else
{
if(cha[]+==cha[])
ans[]=cha[],ans[]=cha[];
else
ans[]=cha[],ans[]=cha[];
}
}
for(int i=;i<=tot;i++)
for(int j=;j<=tim[ans[i]];j++)
printf("%c",ans[i]+'a');
printf("\n");
}
memset(cha,,sizeof cha);tot=;
memset(ch,,sizeof ch);
memset(tim,,sizeof tim);
}
return ;
}

CodeForces 1156C

题意:给一串数列a与数字z,若|ai-aj|>=z,则ai与aj可以匹配。一个数只能匹配一次,求最大匹配数。

本能地给数列排序后,发现新数列有这样一个性质:若有两个匹配之间跨越范围不相交,那么我们可以让它们变成相交的,这样不会影响它们对答案的贡献。但这个性质反过来不一定成立,所以我们匹配时最好让它们相交。

把数列的中点取出,把中点右边的点当做匹配的右端点,左边的当做左端点,依次匹配就好了。这样做可以让所有匹配跨越范围都经过中点,即在中点相交。

论证一下严谨性。如果有一边的点能形成不过中点的匹配,那么它肯定能通过另一边的某个点变为过中点的匹配(因为取的是中点,两边点的个数最多相差1,所以另一边肯定存在一个点能保证形成新的匹配)。

code

#include<cstdio>
#include<algorithm>
using namespace std;
int n,z,num[],ans,vis[];
int main()
{
scanf("%d%d",&n,&z);
for(int i=;i<=n;i++)
scanf("%d",&num[i]);
sort(num+,num++n);
for(int i=(+n)/+,j=;i<=n;i++)
{
while(vis[j])j++;
if(!vis[i]&&!vis[j]&&num[i]-num[j]>=z)
vis[i]=vis[j]=,ans++,j++;
}
printf("%d\n",ans);
}

CodeForces 1156D

题意:给一棵树,边的权值只有0和1。数对(x,y),x到y的路径上经过权值为0的边后就再也没有经过权值为1的边,求满足条件的数对的个数。

用并查集求出所有边权只含0和1的连通块,设每个连通块的点的个数为siz。然后分类讨论,只含权值为1或0的边的路径,则每个连通块的贡献为siz*(siz-1)。含权值为0和权值为1的边的路径,枚举路径上01转变的点,找到包含它的只含0的连通块i与只含1的连通块j,产生的贡献为(sizi-1)*(sizj-1)。

(不需要担心两个联通块还有其它公共点,因为这是棵树)

看到zzwy大佬还有一种巧妙的算法,直接枚举1.0转变的点,找到包含它的只含0的连通块i与只含1的连通块j,产生的贡献为sizi*sizj-1,这样还同时枚举了边权只含0或1的情况,减去1是去掉自己到自己。

code

#include<cstdio>
int ori[][],n,tim[][];
long long ans=;
int find(int x,int k){return !ori[x][k]?x:ori[x][k]=find(ori[x][k],k);}
int main()
{
scanf("%d",&n);
for(int i=,a,b,c;i<=n-;i++)
{
scanf("%d%d%d",&a,&b,&c);
int t1=find(a,c),t2=find(b,c);
if(t1!=t2)
ori[t1][c]=t2;
}
for(int i=;i<=n;i++)
tim[find(i,)][]++,tim[find(i,)][]++;
for(int i=;i<=n;i++)
ans+=1ll*(tim[find(i,)][])*(tim[find(i,)][])-;
printf("%lld\n",ans);
}

CodeForces 1156E

题意:给一个数列p,求所有的数对(l,r)的个数,满足pl+pr=maxri=lpi。

这题抄的题解和代码:

对于每个数a,我们可以用单调队列求出它左边第一个和右边第一个比它大的数al与ar,那么中间的这段区间(l,r)它就是最大值,之后就暴力枚举就好了。通过类似启发式合并的思想(反正我还没学)可以证明复杂度为nlogn。

code

#include<cstdio>
#define maxn 200005
int q[maxn],be=,en,n,p[maxn],pos[maxn],L[maxn],R[maxn];
long long ans;
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%d",&p[i]),pos[p[i]]=i;p[n+]=;p[]=;
for(int i=;i<=n+;i++)
{for(;be<=en&&p[q[en]]<p[i];en--);L[i]=q[en];q[++en]=i;}
for(int i=n+;i>=;i--)
{for(;be<=en&&p[q[en]]<p[i];en--);R[i]=q[en];q[++en]=i;}
for(int i=;i<=n;i++)
{
if(i-L[i]<R[i]-i)
for(int j=L[i]+;j<i;j++)
{ if(R[i]>pos[p[i]-p[j]]&&pos[p[i]-p[j]]>i)ans++;}
else
for(int j=R[i]-;i<j;j--)
{ if(L[i]<pos[p[i]-p[j]]&&pos[p[i]-p[j]]<i)ans++;}
}
printf("%I64d\n",ans);
}

CodeForces 1156F

题意:给一堆牌,随便拿,若这次的值小于上次则失败,等于上次的值则成功,大于上次的值则继续游戏,求胜利的期望值。

第一道自己写的概率dpQAQ

首先对于任何一个不失败的状态,摸到牌形成的序列应该是不下降的,所以先排个序。我们可以假设dp[i][j]表示第i张牌摸到了值为j的牌且游戏未结束的期望值。因为序列不下降且游戏尚未结束,那么值为j的牌就只用了一张。则dp[i][j]可以由dp[i+1][k](k>j)转移过来。首先,先预处理出每个数字的个数cnt,然后就可以进行转移了。dp[i][j]的期望值应该是 (cntj-1)/n-i 加上(∑dp[i+1][k])/(n-i)(k>j),即下一次抽到j的期望值加上之后获胜的期望值,再用前缀和优化一下就好了。

code

#include<cstdio>
#include<algorithm>
#define maxn 5005
#define mod 998244353
using namespace std;
int n,a[maxn],inv[maxn],num[maxn],cnt[maxn],f[maxn][maxn],flag=;
int main()
{
scanf("%d",&n);
inv[]=;for(int i=;i<=n;i++)inv[i]=1ll*inv[mod%i]*(mod-mod/i)%mod;
for(int i=;i<=n;i++)scanf("%d",&a[i]);
sort(a+,a++n);
for(int i=;i<=n;cnt[a[i]]++,i++)
if(!cnt[a[i]])num[++num[]]=a[i];
sort(num+,num++num[]);
for(int i=n;i>=;i--)
{
long long sum=;
for(int k=;k<=num[];k++)
sum=(sum+1ll*f[flag^][k]*cnt[num[k]]%mod*inv[n-i]%mod)%mod;
for(int j=;j<=num[];j++)
{
sum=(sum-1ll*f[flag^][j]*cnt[num[j]]%mod*inv[n-i]%mod+mod)%mod;
f[flag][j]=(1ll*(cnt[num[j]]-)*inv[n-i]%mod+sum)%mod;
}
flag^=;
}
int ans=;
for(int i=;i<=num[];i++)
ans=(ans+1ll*f[flag^][i]*cnt[num[i]]%mod*inv[n]%mod)%mod;
printf("%d\n",ans);
}

CodeForces 1156G

恕在下不肖,真的不会。

Educational Codeforces Round 64(ECR64)的更多相关文章

  1. codeforces Educational Codeforces Round 16-E(DP)

    题目链接:http://codeforces.com/contest/710/problem/E 题意:开始文本为空,可以选择话费时间x输入或删除一个字符,也可以选择复制并粘贴一串字符(即长度变为两倍 ...

  2. Educational Codeforces Round 64部分题解

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

  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 部分题解

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

  5. 【Codeforces】Educational Codeforces Round 46(Contest 1000)

    题目 传送门:QWQ A:Codehorses T-shirts 题意: 给定一些字符串表示去年和今年的衣服型号大小( XL XXL M...... ),要求用最少的次数把去年的衣服大小改成今年需要的 ...

  6. Codeforces Round #328(Div2)

    CodeForces 592A 题意:在8*8棋盘里,有黑白棋,F1选手(W棋往上-->最后至目标点:第1行)先走,F2选手(B棋往下-->最后至目标点:第8行)其次.棋子数不一定相等,F ...

  7. Codeforces Round #326(Div2)

    CodeForces 588A 题意:Duff喜欢吃肉,想在接下来的n天,每天都有Ai斤肉吃,但每一天肉的单价Pi不定,肉 可以保存不过期,现已知n天每天肉的斤数Ai,以及单价Pi,为了使每天都   ...

  8. Educational Codeforces Round 64 (Rated for Div. 2)D(并查集,图)

    #include<bits/stdc++.h>using namespace std;int f[2][200007],s[2][200007];//并查集,相邻点int find_(in ...

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

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

随机推荐

  1. 深入理解JVM(五) -- 垃圾回收算法

    上篇文章我们了解到哪些内存区域和哪些对象可以被回收,这篇文章我们就来了解一下具体的垃圾回收算法的思路,不讨论具体的实现. 一 最基础算法 标记-清除(Mark-Swap) 为什么说他是最基础的算法,因 ...

  2. Vue项目中遇到的问题汇总

    一.打包后的打开index.html页面空白的几种情况: 引入的css.js路径报错,此时解决方法:把vue.config.js中的增加publicPath: ‘./’ 或者把原来的baseUrl改为 ...

  3. 原生JS-----一个剪刀石头布游戏

    html: <h1>这是一个剪刀石头布游戏</h1> <h2>请出拳吧!少年!</h2> <h3>您已经获胜了<span id=&qu ...

  4. CSS是什么

    css是层叠样式表(英文全称:Cascading Style Sheets)是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一个子集)等文件样式的计算机语言. CSS不 ...

  5. 转换属性transform

    transform: rotate(45deg);旋转 rotate(值) 值为正,表示元素顺时针旋转 值为负,表示元素逆时针旋转 transform: translate(200px,100px); ...

  6. MySQL Backup--Xtrabackup远程备份和限速备份

    使用xbstream 备份到远程服务器 ##xbstream 备份到远程服务器 innobackupex \ --defaults-file="/export/servers/mysql/e ...

  7. Linux环境下安装RabbitMQ

    首先RabbitMQ是使用erLang编写的开源消息中间件.所以需要先安装erlang环境. 我使用的是CentOS的系统安装erlang21.0的步骤如下: #下载安装包 (下面是我用的比较匹配的版 ...

  8. MySQL中使用函数时,与后面括号不能之间不能根空格

    修改前代码: select MAX (article_order) from mall_school_article where 1=1 and is_deleted = 0 and status = ...

  9. [openssl] 使用openssl生成证书

    使用openssl生成带域名的证书,SAN,subjectAltName, subject alternative name, DNS. 1. 生成私钥 openssl genrsa - 2. 编写配 ...

  10. java操作redis(jedis)常用方法示例

    说明:redis命令和jedis方法名基本是一一对应的 Redis常用命令1 连接操作命令 ● quit:关闭连接(connection) ● auth:简单密码认证 ● help cmd: 查看cm ...