zoukankan      html  css  js  c++  java
  • Codeforces Round #382 (Div. 2) 解题报告

      CF一如既往在深夜举行,我也一如既往在周三上午的C++课上进行了virtual participation。这次div2的题目除了E题都水的一塌糊涂,参赛时的E题最后也没有几个参赛者AC,排名又成为了手速与精准的竞争……(遗憾,如果参加了一定可以上分的吧orz)

      A题:

      先判断起点和终点的距离是否被每次跳的距离整除,如果不整除就到不了。再检验跳跃过程中的落点是否均合法即可。

      

     1 #include<stdio.h>
     2 #include<bits/stdc++.h>
     3 #include <iostream>
     4 using namespace std;
     5 typedef long long ll;
     6 int k,n;
     7 char a[200];
     8 void solve(int st,int en)
     9 {
    10     if((en-st)%k!=0)
    11     {
    12         printf("NO
    ");
    13         return ;
    14     }
    15     int j;
    16     for(j=st+k;j<en;j+=k)
    17     {
    18         if(a[j]=='#')
    19         {
    20             printf("NO
    ");
    21             return;
    22         }
    23     }
    24 //    if(j<en)
    25         printf("YES
    ");
    26 
    27 }
    28 int main()
    29 {
    30     int i,si,ei;
    31     scanf("%d%d",&n,&k);
    32     scanf("%s",a);
    33     for(i=0;i<n;i++)
    34     {
    35         if(a[i]=='G')
    36             ei=i;
    37         if(a[i]=='T')
    38             si=i;
    39     }
    40     if(ei<si)
    41         swap(ei,si);
    42     solve(si,ei);
    43     return 0;
    44 }

      B题:

      根据题意,只需要想清楚最佳分配方案。根据排序不等式,即可轻松找到最佳方案。将人排序后,让从大到小的前若干个人分到人数小的城市,接下来再若干人分到人数多的城市即可得到最大值。

      

     1 #include<stdio.h>
     2 #include<bits/stdc++.h>
     3 #include <iostream>
     4 using namespace std;
     5 typedef long long ll;
     6 ll n,a[2],ren[100005],i,he1=0,he2=0;
     7 double an=0;
     8 int main()
     9 {
    10 
    11     scanf("%I64d%I64d%I64d",&n,&a[0],&a[1]);
    12     if(a[0]>a[1])
    13         swap(a[0],a[1]);
    14     for(i=0;i<n;i++)
    15         scanf("%I64d",&ren[i]);
    16     sort(ren,ren+n);
    17 for(i=n-1;i>=n-a[0];i--)
    18 {
    19     he1+=ren[i];
    20 }
    21 for(i=n-a[0]-1;i>=n-a[0]-a[1];i--)
    22 {
    23     he2+=ren[i];
    24 }
    25 an=(1.0*he1/a[0])+(1.0*he2/a[1]);
    26 printf("%.8f
    ",an);
    27     return 0;
    28 }

      C题:

      观察比赛场次和人数的关系,以及比赛场次何时+1即可发现这题本质上是斐波那契数列。设人x时开始变为最多比赛q场,人y时开始变为最多比赛q+1场,则人(x+y)时,前x个人可以找到比赛q场的唯一到最后的选手,后y个人可以找到比赛(q+1)场后唯一到最后的选手,这两个人可以比赛,并且会得出胜者,如果后y人中的胜者获得胜利,就构造出了最多参加(q+2)场的情况。并且可以归纳证明这是最少的人数。于是就证明了本题斐波那契数列的本质。

      

     1 #include<stdio.h>
     2 #include<bits/stdc++.h>
     3 #include <iostream>
     4 using namespace std;
     5 typedef long long ll;
     6 ll n;
     7 ll fi(ll x)
     8 {
     9     if(x==2)
    10         return 1;
    11     if(x==3)
    12         return 2;
    13     else
    14 
    15     {
    16         ll x1,x2,tem,cnt;
    17         cnt=2;x1=3;x2=2;
    18         while(x1<x)
    19         {
    20             tem=x1;
    21             x1=x1+x2;
    22             x2=tem;
    23             cnt++;
    24         }
    25         if(x1==x)
    26             return cnt;
    27         else
    28             return cnt-1;
    29     }
    30 }
    31 int main()
    32 {
    33     scanf("%I64d",&n);
    34     printf("%I64d
    ",fi(n));
    35     return 0;
    36 }

      D题:

      乍一看和素数相关,数还特别大,比较吓人。而实际上利用哥德巴赫猜想的内容即可轻松解决(虽然还没有证明为真,但这样数量级的数之前都已经用计算机验证过了)

      注意到:任何一个大于2的偶数都是两个素数之和。那么对于输入的如果是偶数,2就输出1(因为本身是质数),其余就输出2(根据猜想,可以分为两个质数之和)

          任何大于5的奇数都是三个素数之和。那么对于输入的如果是奇数,判断是否为质数(这里我比较懒,直接用了拉宾米勒,实际上简单的从2到根号n循环一遍就可以),是就输出1,不是的话再看(n-2)是否为质数,如果是,就可以将其分为2和(n-2)这样两个质数,那么就输出2。不然就只能根据猜想,一定可以分为3个质数,输出3。

      

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 #include<time.h>
      5 #include<iostream>
      6 #include<string.h>
      7 #include<math.h>
      8 #include<algorithm>
      9 using namespace std;
     10 
     11 //****************************************************************
     12 // Miller_Rabin 算法进行素数测试
     13 //速度快,而且可以判断 <2^63的数
     14 //****************************************************************
     15 const int S=20;//随机算法判定次数,S越大,判错概率越小
     16 
     17 
     18 //计算 (a*b)%c.   a,b都是long long的数,直接相乘可能溢出的
     19 //  a,b,c <2^63
     20 long long mult_mod(long long a,long long b,long long c)
     21 {
     22     a%=c;
     23     b%=c;
     24     long long ret=0;
     25     while(b)
     26     {
     27         if(b&1){ret+=a;ret%=c;}
     28         a<<=1;
     29         if(a>=c)a%=c;
     30         b>>=1;
     31     }
     32     return ret;
     33 }
     34 
     35 
     36 
     37 //计算  x^n %c
     38 long long pow_mod(long long x,long long n,long long mod)//x^n%c
     39 {
     40     if(n==1)return x%mod;
     41     x%=mod;
     42     long long tmp=x;
     43     long long ret=1;
     44     while(n)
     45     {
     46         if(n&1) ret=mult_mod(ret,tmp,mod);
     47         tmp=mult_mod(tmp,tmp,mod);
     48         n>>=1;
     49     }
     50     return ret;
     51 }
     52 
     53 
     54 
     55 
     56 
     57 //以a为基,n-1=x*2^t      a^(n-1)=1(mod n)  验证n是不是合数
     58 //一定是合数返回true,不一定返回false
     59 bool check(long long a,long long n,long long x,long long t)
     60 {
     61     long long ret=pow_mod(a,x,n);
     62     long long last=ret;
     63     for(int i=1;i<=t;i++)
     64     {
     65         ret=mult_mod(ret,ret,n);
     66         if(ret==1&&last!=1&&last!=n-1) return true;//合数
     67         last=ret;
     68     }
     69     if(ret!=1) return true;
     70     return false;
     71 }
     72 
     73 // Miller_Rabin()算法素数判定
     74 //是素数返回true.(可能是伪素数,但概率极小)
     75 //合数返回false;
     76 
     77 bool Miller_Rabin(long long n)
     78 {
     79     if(n<2)return false;
     80     if(n==2)return true;
     81     if((n&1)==0) return false;//偶数
     82     long long x=n-1;
     83     long long t=0;
     84     while((x&1)==0){x>>=1;t++;}
     85     for(int i=0;i<S;i++)
     86     {
     87         long long a=rand()%(n-1)+1;//rand()需要stdlib.h头文件
     88         if(check(a,n,x,t))
     89             return false;//合数
     90     }
     91     return true;
     92 }
     93 typedef long long ll;
     94 ll n;
     95 int main()
     96 {
     97     scanf("%I64d",&n);
     98     if(n==2)
     99     {printf("1
    ");return 0;}
    100     if(n%2==0)
    101         printf("2
    ");
    102     else
    103     {
    104         if(Miller_Rabin(n))
    105             {
    106                 printf("1
    ");
    107 
    108             }
    109         else
    110             {
    111                 if(Miller_Rabin(n-2))
    112                     printf("2
    ");
    113                 else
    114                     printf("3
    ");
    115             }
    116 
    117     }
    118     return 0;
    119 }

      E题好难,貌似还得用到树状dp,还没有学到orz,等以后再回来填坑。(捂脸,估计看解题报告的大家其实想看的就是E题吧……)

  • 相关阅读:
    shell脚本day06-sed
    shell脚本day05-交互式输入与for语句
    shell脚本day04-if语句
    shell脚本day04-grep与正则表达式
    shell脚本day03-编程原理
    shell脚本day02-重定向与管道符
    编程原理大致介绍
    进程管理
    Linux网络
    shell脚本--grep以及正则表达式
  • 原文地址:https://www.cnblogs.com/quintessence/p/6116792.html
Copyright © 2011-2022 走看看