Educational Codeforces Round 64

CodeForces 1156A

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

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

code

  1. #include<cstdio>
  2. int n,fig[],ans,flag,haha[][];
  3. int main()
  4. {
  5. scanf("%d",&n);
  6. haha[][]=;haha[][]=;
  7. haha[][]=;haha[][]=;
  8. haha[][]=;haha[][]=;
  9. for(int i=;i<=n;i++)
  10. {
  11. scanf("%d",&fig[i]);
  12. ans+=haha[fig[i-]][fig[i]];
  13. if(fig[i]==&&fig[i-]==&&fig[i-]==)ans--;
  14. if(ans>=)
  15. {
  16. printf("Infinite\n");
  17. return ;
  18. }
  19. }
  20. printf("Finite\n");
  21. printf("%d",ans);
  22. }

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

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5. int T,cha[],tot,tim[],ans[];
  6. char ch[];
  7. int main()
  8. {
  9. scanf("%d",&T);
  10. while(T--)
  11. {
  12. scanf("%s",ch+);
  13. int len=strlen(ch+);
  14. for(int i=;i<=len;i++)
  15. {
  16. if(!tim[ch[i]-'a'])
  17. cha[++tot]=ch[i]-'a';
  18. tim[ch[i]-'a']++;
  19. }
  20. sort(cha+,cha++tot);
  21. if((tot==&&cha[]+==cha[]&&cha[]+==cha[])||(tot==&&cha[]+==cha[]))
  22. printf("No answer\n");
  23. else
  24. {
  25. if(tot%==)
  26. {
  27. int mid1=tot/,mid2=mid1+;
  28. ans[]=cha[mid2];ans[]=cha[];
  29. ans[]=cha[tot];ans[]=cha[mid1];
  30. int l=;
  31. for(int i=;i<mid1;i++)
  32. ans[++l]=cha[tot-i+],ans[++l]=cha[i];
  33. }
  34. else
  35. {
  36. ans[]=cha[tot/+];
  37. if(tot!=||(tot==&&cha[]+!=cha[]&&cha[]+!=cha[]))
  38. for(int i=;i<=tot/;i++)
  39. ans[i*]=cha[i],ans[i*+]=cha[tot-i+];
  40. else
  41. {
  42. if(cha[]+==cha[])
  43. ans[]=cha[],ans[]=cha[];
  44. else
  45. ans[]=cha[],ans[]=cha[];
  46. }
  47. }
  48. for(int i=;i<=tot;i++)
  49. for(int j=;j<=tim[ans[i]];j++)
  50. printf("%c",ans[i]+'a');
  51. printf("\n");
  52. }
  53. memset(cha,,sizeof cha);tot=;
  54. memset(ch,,sizeof ch);
  55. memset(tim,,sizeof tim);
  56. }
  57. return ;
  58. }

CodeForces 1156C

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

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

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

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

code

  1. #include<cstdio>
  2. #include<algorithm>
  3. using namespace std;
  4. int n,z,num[],ans,vis[];
  5. int main()
  6. {
  7. scanf("%d%d",&n,&z);
  8. for(int i=;i<=n;i++)
  9. scanf("%d",&num[i]);
  10. sort(num+,num++n);
  11. for(int i=(+n)/+,j=;i<=n;i++)
  12. {
  13. while(vis[j])j++;
  14. if(!vis[i]&&!vis[j]&&num[i]-num[j]>=z)
  15. vis[i]=vis[j]=,ans++,j++;
  16. }
  17. printf("%d\n",ans);
  18. }

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

  1. #include<cstdio>
  2. int ori[][],n,tim[][];
  3. long long ans=;
  4. int find(int x,int k){return !ori[x][k]?x:ori[x][k]=find(ori[x][k],k);}
  5. int main()
  6. {
  7. scanf("%d",&n);
  8. for(int i=,a,b,c;i<=n-;i++)
  9. {
  10. scanf("%d%d%d",&a,&b,&c);
  11. int t1=find(a,c),t2=find(b,c);
  12. if(t1!=t2)
  13. ori[t1][c]=t2;
  14. }
  15. for(int i=;i<=n;i++)
  16. tim[find(i,)][]++,tim[find(i,)][]++;
  17. for(int i=;i<=n;i++)
  18. ans+=1ll*(tim[find(i,)][])*(tim[find(i,)][])-;
  19. printf("%lld\n",ans);
  20. }

CodeForces 1156E

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

这题抄的题解和代码:

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

code

  1. #include<cstdio>
  2. #define maxn 200005
  3. int q[maxn],be=,en,n,p[maxn],pos[maxn],L[maxn],R[maxn];
  4. long long ans;
  5. int main()
  6. {
  7. scanf("%d",&n);
  8. for(int i=;i<=n;i++)scanf("%d",&p[i]),pos[p[i]]=i;p[n+]=;p[]=;
  9. for(int i=;i<=n+;i++)
  10. {for(;be<=en&&p[q[en]]<p[i];en--);L[i]=q[en];q[++en]=i;}
  11. for(int i=n+;i>=;i--)
  12. {for(;be<=en&&p[q[en]]<p[i];en--);R[i]=q[en];q[++en]=i;}
  13. for(int i=;i<=n;i++)
  14. {
  15. if(i-L[i]<R[i]-i)
  16. for(int j=L[i]+;j<i;j++)
  17. { if(R[i]>pos[p[i]-p[j]]&&pos[p[i]-p[j]]>i)ans++;}
  18. else
  19. for(int j=R[i]-;i<j;j--)
  20. { if(L[i]<pos[p[i]-p[j]]&&pos[p[i]-p[j]]<i)ans++;}
  21. }
  22. printf("%I64d\n",ans);
  23. }

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

  1. #include<cstdio>
  2. #include<algorithm>
  3. #define maxn 5005
  4. #define mod 998244353
  5. using namespace std;
  6. int n,a[maxn],inv[maxn],num[maxn],cnt[maxn],f[maxn][maxn],flag=;
  7. int main()
  8. {
  9. scanf("%d",&n);
  10. inv[]=;for(int i=;i<=n;i++)inv[i]=1ll*inv[mod%i]*(mod-mod/i)%mod;
  11. for(int i=;i<=n;i++)scanf("%d",&a[i]);
  12. sort(a+,a++n);
  13. for(int i=;i<=n;cnt[a[i]]++,i++)
  14. if(!cnt[a[i]])num[++num[]]=a[i];
  15. sort(num+,num++num[]);
  16. for(int i=n;i>=;i--)
  17. {
  18. long long sum=;
  19. for(int k=;k<=num[];k++)
  20. sum=(sum+1ll*f[flag^][k]*cnt[num[k]]%mod*inv[n-i]%mod)%mod;
  21. for(int j=;j<=num[];j++)
  22. {
  23. sum=(sum-1ll*f[flag^][j]*cnt[num[j]]%mod*inv[n-i]%mod+mod)%mod;
  24. f[flag][j]=(1ll*(cnt[num[j]]-)*inv[n-i]%mod+sum)%mod;
  25. }
  26. flag^=;
  27. }
  28. int ans=;
  29. for(int i=;i<=num[];i++)
  30. ans=(ans+1ll*f[flag^][i]*cnt[num[i]]%mod*inv[n]%mod)%mod;
  31. printf("%d\n",ans);
  32. }

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. 混编用到 C++中数组和vector 复习下大学课本

    本文基于邓俊辉编著<数据结构(C++语言版)(第3版)>.<C++ Primer(第5版)>以及网上的相关博文而写,博主水平有限,若有不妥处,欢迎指出. 一.数组 C++中数组 ...

  2. PHP 中使用ajax时一些常见错误总结整理

    这篇文章主要介绍了PHP 中使用ajax时一些常见错误总结整理的相关资料,需要的朋友可以参考下 PHP作为后端时,前端js使用ajax技术进行相互信息传送时,经常会出错误,对于新手来说有些手足无措.总 ...

  3. js中for循环点击事件(闭包)

    <!DOCTYPE html><html lang="en"><head> <meta charset="utf-8" ...

  4. 【iOS录音与播放】实现利用音频队列,通过缓存进行对声音的采集与播放

    都说iOS最恶心的部分是流媒体,其中恶心的恶心之处更在即时语音. 所以我们先不谈即时语音,研究一下,iOS中声音采集与播放的实现. 要在iOS设备上实现录音和播放功能,苹果提供了简单的做法,那就是利用 ...

  5. Debian9.5系统安装

    1.镜像下载地址 http://cdimage.debian.org/cdimage/archive/ 2.开始安装 如果有配置网络地址,可以手动配置或者跳过等系统安装好后配置.  至此debian9 ...

  6. Java--8--新特性--接口中的变化!!

    package InterfaceP; public interface Interface1 { default String getName(){ return "Interface1& ...

  7. C++中string::find()函数和string::npos函数的使用

    1. string::find()函数和string::npos函数的介绍 我们在学习C++的时候必不可少的使用到string类中的find()函数,它是一个查找函数,功能还是很强大的,但是此处我们不 ...

  8. 怎样制作一个 Python Egg

    from:http://liluo.org/blog/2012/08/how-to-create-python-egg/ 制作打包一个 Python Egg 并部署整个过程还蛮有意思的,下面小教程(这 ...

  9. redis都有哪些数据类型?分别在哪些场景下使用比较合适?

    (1)string 这是最基本的类型了,没啥可说的,就是普通的set和get,做简单的kv缓存 (2)hash 这个是类似map的一种结构,这个一般就是可以将结构化的数据,比如一个对象(前提是这个对象 ...

  10. python中的logging日志模块

    日志是程序不可或缺的一部分.它可以记录程序的运行情况,帮助我们更便捷地发现问题,而python中的logging日志模块给我们提供了这个机会. logging给我们提供了五种函数用来输出日志:debu ...