比赛链接:

https://codeforces.com/contest/1156

A. Inscribed Figures

题意:

给出$n(2\leq n\leq 100)$个数,只含有1,2,3,分别代表圆,高与底相等的三角形,正方形

$a_{i+1}$在$a_{i}$的里面,$a_{i+1}$的面积尽可能的大

求不同的交点个数

分析:

注意正方形里面一个圆,再里面一个三角形的时候,有一个交点重合

ac代码:

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. const int maxn=1e5+10;
  5. const int maxm=200000*2+10;
  6. const int mod=1e9+7;
  7. int num[maxn];
  8. ll ans;
  9. int main()
  10. {
  11. int n;
  12. scanf("%d",&n);
  13. for(int i=1;i<=n;i++)
  14. scanf("%d",&num[i]);
  15. for(int i=2;i<=n;i++)
  16. {
  17. if(num[i]==1)
  18. {
  19. if(num[i-1]==2)ans+=3;
  20. if(num[i-1]==3)ans+=4;
  21.  
  22. }
  23. if(num[i]==2)
  24. {
  25. if(num[i-1]==1)
  26. {
  27. if(i-2>=1&&num[i-2]==3)
  28. ans+=2;
  29. else ans+=3;
  30. }
  31. if(num[i-1]==3)ans=1e18;
  32. }
  33. if(num[i]==3)
  34. {
  35. if(num[i-1]==1)ans+=4;
  36. if(num[i-1]==2)ans=1e18;
  37. }
  38. }
  39. if(ans>=1e17)
  40. cout<<"Infinite"<<endl;
  41. else
  42. {
  43. cout<<"Finite"<<endl;
  44. cout<<ans<<endl;
  45. }
  46. return 0;
  47. }

  

B. Ugly Pairs

题意:

给出一个字符串$s(1\leq |s|\leq 100)$,重排它们,让每对相邻的字符在$ascii$表中不相邻

分析:

将$a,c,e,g...$放一个集合,将$b,d,f,h...$放另一个集合,看它们是否能连线在一起

ac代码:

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. const int maxn=100+10;
  5. const int maxm=200000*2+10;
  6. const int mod=1e9+7;
  7. int num[30];
  8. char word[maxn];
  9. int main()
  10. {
  11. int T;
  12. scanf("%d",&T);
  13. while(T--)
  14. {
  15. getchar();
  16. scanf("%s",word);
  17. int gkd=0;
  18. for(int i=0;word[i];i++)
  19. if((int)word[i]%2!=(int)word[0]%2)gkd=1;
  20. if(gkd==0)
  21. {
  22. printf("%s\n",word);
  23. continue;
  24. }
  25. memset(num,0,sizeof(num));
  26. for(int i=0; word[i]; i++)
  27. num[word[i]-'a']++;
  28. int a,b,fla=0;
  29. for( int i=0; i<26; i++)
  30. for(int j=0; j<26; j++)
  31. if(i%2==0&&j%2==1&&abs(i-j)!=1&&num[j]&&num[i])
  32. {
  33. a=i,b=j;
  34. fla=1;
  35. }
  36. if(fla==0)
  37. {
  38. printf("No answer\n");
  39. continue;
  40. }
  41. num[a]--;
  42. num[b]--;
  43. for(int i=0; i<26; i+=2)
  44. for(int j=0; j<num[i]; j++)
  45. printf("%c",(char)(i+'a'));
  46. printf("%c%c",(char)(a+'a'),(char)(b+'a'));
  47. for(int i=1; i<26; i+=2)
  48. for(int j=0; j<num[i]; j++)
  49. printf("%c",(char)(i+'a'));
  50. printf("\n");
  51. }
  52. return 0;
  53. }

  

C. Match Points

题意:

给出n个数,组成最多的数对,满足$|a_i-a_j|\geq d$

分析:

这题一看就是贪心,但是,我的策略是,用最小的去匹配最小能匹配的,wa

例如:

4 2

1 3 4 7

最优解是$(1,4)(3,7)$

正确匹配方式是,用前面一部分匹配后面一部分,对答案二分即可

ac代码:

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. const int maxn=2e5+10;
  5. const int maxm=200000*2+10;
  6. const int mod=1e9+7;
  7. int n,d,num[maxn];
  8. bool check(int x)
  9. {
  10. int a=x,b=n;
  11. for(;a>=1;a--,b--)
  12. if(num[b]-num[a]<d)return 0;
  13. return 1;
  14. }
  15. int main()
  16. {
  17. scanf("%d %d",&n,&d);
  18. for(int i=1;i<=n;i++)
  19. scanf("%d",&num[i]);
  20. sort(num+1,num+1+n);
  21. int st=0,en=n/2;
  22. while(st!=en)
  23. {
  24. int md=(st+en)/2;
  25. if(check(md+1))st=md+1;
  26. else en=md;
  27. }
  28. printf("%d\n",st);
  29. return 0;
  30. }

D. 0-1-Tree

题意:

给出一颗节点数为$n$的树,每条边有一个属性0或者1

求出点对$(a,b)$的数量,满足$a$到$b$的最短路线上,经过1之后不经过0

分析:

这样的点对有三种情况

1.$(a,b)$的路径只包含0

2.$(a,b)$的路径只包含1

3.$(a,b)$的路径先全是0,再全是1

对于题目的样例有$ans=5\times 5-5+3\times 3-3+4\times 2=34$

用两个并查集记录0和1的集合和大小。

ac代码:

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. const int maxn=200000+10;
  5. const int maxm=200000*2+10;
  6. const int mod=1e9+7;
  7. int boss[maxn][2];
  8. ll siz[maxn][2],ans;
  9. int ma[maxn][2],n;
  10. int fin0(int x)
  11. {
  12. if(boss[x][0]==x)
  13. return x;
  14. return boss[x][0]=fin0(boss[x][0]);
  15. }
  16. int fin1(int x)
  17. {
  18. if(boss[x][1]==x)
  19. return x;
  20. return boss[x][1]=fin1(boss[x][1]);
  21. }
  22. void uni0(int a,int b)
  23. {
  24. boss[fin0(a)][0]=fin0(b);
  25. }
  26. void uni1(int a,int b)
  27. {
  28. boss[fin1(a)][1]=fin1(b);
  29. }
  30. int main()
  31. {
  32. scanf("%d",&n);
  33. for(int i=1; i<=n; i++)
  34. boss[i][0]=boss[i][1]=i;
  35. for(int i=1; i<=n-1; i++)
  36. {
  37. int a,b,c;
  38. scanf("%d %d %d",&a,&b,&c);
  39. ma[a][c]=b;
  40. ma[b][c]=a;
  41. if(c==1)
  42. uni1(a,b);
  43. else
  44. uni0(a,b);
  45. }
  46. for(int i=1; i<=n; i++)
  47. {
  48. siz[fin0(i)][0]++;
  49. siz[fin1(i)][1]++;
  50. //cout<<fin1(i)<<endl;
  51. }
  52. for(int i=1; i<=n; i++)
  53. {
  54. if(boss[i][1]==i)
  55. {
  56. //cout<<siz[i][1]<<endl;
  57. ans+=siz[i][1]*siz[i][1]-siz[i][1];
  58. }
  59.  
  60. if(boss[i][0]==i)
  61. {
  62. //cout<<siz[i][0]<<endl;
  63. ans+=siz[i][0]*siz[i][0]-siz[i][0];
  64. }
  65.  
  66. if(ma[i][0]&&ma[i][1])
  67. {
  68. ans+=(siz[fin0(i)][0]-1)*(siz[fin1(i)][1]-1);
  69. //cout<<i<<" "<<(siz[fin0(i)][0]-1)*(siz[fin1(i)][1]-1)<<endl;
  70. }
  71. //cout<<"ans="<<ans<<endl;
  72.  
  73. }
  74. printf("%lld\n",ans);
  75. return 0;
  76. }

E. Special Segments of Permutation

题意:

给出$n(3 \le n \le 2 \cdot 10^5)$个数,满足$1 \le p_i \le n$,并且每个数只出现一次

计算区间$(l,r)$的数量,满足$p_l + p_r = \max \limits_{i = l}^{r} p_i$

分析:

用单调栈求出以坐标$i$为最大值的最大区间

然后遍历区间左边或者右边的数,看是否能在另一边找到可以匹配的数

遍历左边或者右边,取决于左右区间的大小,不然一定超时

最初我用递归分治去做,ac了,但是,题目的数据很少,我自己造的数据,会栈溢出

ac代码:

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. const int maxn=2e5+10;
  5. const int maxm=200000*2+10;
  6. const int mod=1e9+7;
  7. struct Node
  8. {
  9. int l,r,x;
  10. }node[maxn];
  11. int sta[maxn],top=-1,n,pos[maxn];
  12. int main()
  13. {
  14. scanf("%d",&n);
  15. for(int i=1;i<=n;i++)
  16. {
  17. scanf("%d",&node[i].x);
  18. pos[node[i].x]=i;
  19. node[i].l=i;
  20. }
  21. for(int i=1;i<=n;i++)
  22. {
  23. while(top!=-1&&node[i].x>node[sta[top]].x)
  24. {
  25. node[sta[top]].r=i-1;
  26. node[i].l=node[sta[top]].l;
  27. top--;
  28. }
  29. sta[++top]=i;
  30. }
  31. while(top!=-1)
  32. node[sta[top]].r=n,top--;
  33. int ans=0;
  34. for(int i=1;i<=n;i++)
  35. {
  36. if(i-node[i].l<node[i].r-i)
  37. {
  38. for(int j=node[i].l;j<i;j++)
  39. {
  40. int x=pos[node[i].x-node[j].x];
  41. if(x>i&&x<=node[i].r)ans++;
  42. }
  43. }
  44. else
  45. {
  46. for(int j=i+1;j<=node[i].r;j++)
  47. {
  48. int x=pos[node[i].x-node[j].x];
  49. if(x>=node[i].l&&x<i)ans++;
  50. }
  51. }
  52. }
  53. printf("%d\n",ans);
  54. return 0;
  55. }

F. Card Bag

题意:

有$n(2 \le n \le 5000)$个卡片在背包里面,每个卡片有一个属性$a_i(1\leq a_i\leq n)$

每次取出一张卡片属性看作$x$,如果上一张有卡片,把上一张卡片属性看作$y$

如果$x=y$,胜利

如果$x<y$,失败

如果$x>y$,游戏继续

求胜利的期望概率

分析:

这题一看就是概率DP

定义$prob[x][y]$为抽出$x$张不重复的卡牌,以$y$作为最后一张的概率

定义$num[x]$为$x$卡牌的数量

那么:

$$prob[x][y]=\frac{num[y]}{n-x+1}\times \sum_{i=1}^{y-1}prob[x-1][i]$$

再枚举所有胜利的情况,抽$x$张牌,以$y$为最后两张的概率

$$ans=ans+prob[x-1][y]\times \frac{num[y]-1}{n-x+1}$$

ac代码:

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. const int maxn=5e3+10;
  5. const int maxm=200000*2+10;
  6. const int mod=998244353;
  7. ll num[maxn];
  8. ll ans,sum[maxn],prob[maxn][maxn],inv[maxn];
  9. ll qpow(ll x,ll y)
  10. {
  11. ll res=1,k=x;
  12. while(y)
  13. {
  14. if(y&1)res=res*k%mod;
  15. k=k*k%mod;
  16. y/=2;
  17. }
  18. return res;
  19. }
  20. int main()
  21. {
  22. int n;
  23. scanf("%d",&n);
  24. for(int i=1;i<=n;i++)
  25. inv[i]=qpow(i,mod-2);
  26. for(int i=1;i<=n;i++)
  27. {
  28. int x;
  29. scanf("%d",&x);
  30. num[x]++;
  31. }
  32. for(int i=1;i<=n;i++)//prob[x][y]为已经选择了x个数,末尾为y的概率
  33. {
  34. prob[1][i]=num[i]*inv[n]%mod;
  35. for(int len=2;n-len+1>0;len++)
  36. prob[len][i]=sum[len-1]*num[i]%mod*inv[n-len+1]%mod;
  37. for(int len=1;len<=n;len++)
  38. sum[len]=(sum[len]+prob[len][i])%mod;//sum[len]为prob[len][x]的和
  39. }
  40. for(int i=1;i<=n;i++)//枚举胜利的所有情况,选择len+1个数,并且以i作为结尾
  41. if(num[i]>=2)
  42. for(int len=1;len<n;len++)
  43. ans=(ans+prob[len][i]*(num[i]-1)%mod*inv[n-len]%mod)%mod;
  44. cout<<ans<<endl;
  45. return 0;
  46. }

  

总结:

A.没考虑到交点重合的情况,wa了很多发,我应该模拟所有情况的

B.比赛的时候没有思路

C.贪心的策略错了,导致wa了还不知道原因

贪心是最难的算法Orz

E的数据有点少,我可以自己hack我的代码,第一次遇到cf数据有漏洞

栈的深度最大是$5\times 10^{4}$左右,以后要注意

Educational Codeforces Round 64 (Rated for Div. 2) A,B,C,D,E,F的更多相关文章

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

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

  2. 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, ...

  3. 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 ...

  4. Educational Codeforces Round 85 (Rated for Div. 2)

    \(Educational\ Codeforces\ Round\ 85\ (Rated\ for\ Div.2)\) \(A. Level Statistics\) 每天都可能会有人玩游戏,同时一部 ...

  5. Educational Codeforces Round 65 (Rated for Div. 2)题解

    Educational Codeforces Round 65 (Rated for Div. 2)题解 题目链接 A. Telephone Number 水题,代码如下: Code #include ...

  6. Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship

    Problem   Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship Time Limit: 2000 mSec P ...

  7. Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems(动态规划+矩阵快速幂)

    Problem   Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems Time Limit: 3000 mSec P ...

  8. Educational Codeforces Round 43 (Rated for Div. 2)

    Educational Codeforces Round 43 (Rated for Div. 2) https://codeforces.com/contest/976 A #include< ...

  9. Educational Codeforces Round 35 (Rated for Div. 2)

    Educational Codeforces Round 35 (Rated for Div. 2) https://codeforces.com/contest/911 A 模拟 #include& ...

随机推荐

  1. Java门面模式(思维导图)

    图1 门面模式[点击查看图片] 1,实体对象类 package com.cnblogs.mufasa.demo1; //3个子系统,解决问题的实体 public class StoreA { //示意 ...

  2. oracle导入时IMP-00010: 不是有效的导出文件, 头部验证失败

    头部验证失败是由于版本号不同所致,经试验可以通过如下方法进行修改:用notepad++工具打开dmp文件,可以看到头部信息 --TEXPORT:V11.01.00,即为源数据库的版本号,将其修改为目的 ...

  3. NOIP2009-2018简要题解

    口胡警告 NOIP2009 潜伏者 模拟 Hankson 的趣味题 对四个数\(a_0,a_1,b_0,b_1\)分解质因数,结果序列分别记为\(\{p1^{b1}\},\{p2^{b2}\},\{p ...

  4. Javascript简单教程汇总

    什么是函数 一段定义好的代码,并可以反复使用的代码块 函数的作用 提升代码的可复用性,将一段代码进行预定义,需要使用的时候才触发 代码块 形成了一个相对独立的作用域 语法: function  函数名 ...

  5. struts-2.5.14.1 中web.xml的基本配置

    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http:// ...

  6. Nginx如何配置禁止访问某个目录

    location ~* \.(txt|doc)${ root /data/www/wwwroot/test; deny all; }

  7. 文件的空间使用和IO统计

    数据库占用的存储空间,从高层次来看,可以查看数据库文件(数据文件,日志文件)占用的存储空间,从较细的粒度上来看,分为数据表,索引,分区占用的存储空间.监控数据库对象占用的硬盘空间,包括已分配,未分配, ...

  8. scp上传文件到远程服务器

    scp -P 22 E:/download/2028792_www.yeves.cn_nginx/cloud.pem root@ip:/usr/local/src

  9. async/await 处理多个网络请求同步问题

    1.async/await是基于Promise的,是进一步的一种优化,await会等待异步执行完成 getProjectTask(id){ this.axios.get('/api/v1/task/' ...

  10. 【Distributed】限流技巧

    一.概述 1.1 高并发服务限流特技 1.2 为什么要互联网项目要限流 1.3 高并发限流解决方案 二.限流算法 2.1 计数器 2.2 滑动窗口计数 2.3 令牌桶算法 使用RateLimiter实 ...