• 【BestCoder】【Round#41】


    枚举+组合数?+DP+数学问题


      http://bestcoder.hdu.edu.cn/contests/contest_show.php?cid=582

      QAQ许久没打过比赛,来一发BC,结果还是只能做前两题……too young too naive了……

      不过这场比赛前两题被hack&FST的人挺多的?蒟蒻手太慢,造数据也慢,玩不来hack……抢不到QAQ

    A

      给5张牌,问最少换多少张可得到同花顺。

      其实是枚举花色,以及最小的是哪张(其实就是枚举换完以后,得到的是哪五张)看手里有多少张是已经得到的= =

      开个have[i][j]表示手里有花色为 i 数字为 j 的牌(其中,如果手里有A,那么1和14都置为true)

      hack点?没啥吧……可能有的同学是看手里连续拥有最大段是多长,比如手里最长的连续牌是123,那ans=2,但是135也是只需要换两张……

     1 //BestCoder #41 A
     2 #include<vector>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<iostream>
     7 #include<algorithm>
     8 #define rep(i,n) for(int i=0;i<n;++i)
     9 #define F(i,j,n) for(int i=j;i<=n;++i)
    10 #define D(i,j,n) for(int i=j;i>=n;--i)
    11 #define pb push_back
    12 using namespace std;
    13 inline int getint(){
    14     int v=0,sign=1; char ch=getchar();
    15     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
    16     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
    17     return v*sign;
    18 }
    19 const int N=1e5+10,INF=~0u>>2;
    20 typedef long long LL;
    21 /******************tamplate*********************/
    22 
    23 int a[6],b[6];
    24 char s[6][10];
    25 bool have[6][16];
    26 int main(){
    27 #ifndef ONLINE_JUDGE
    28     freopen("A.in","r",stdin);
    29     freopen("A.out","w",stdout);
    30 #endif
    31     int T=getint();
    32     while(T--){
    33         memset(have,0,sizeof have);
    34         memset(a,0,sizeof a);
    35         memset(b,0,sizeof b);
    36         memset(s,0,sizeof s);
    37         F(i,1,5) scanf("%s",s[i]);
    38         F(i,1,5) a[i]=s[i][0]-'A';
    39         F(i,1,5){
    40             b[i]=s[i][1]-'0';
    41             if (s[i][2]>0) b[i]=b[i]*10+s[i][2]-'0';
    42             have[a[i]][b[i]]=1;
    43             if (b[i]==1) have[a[i]][14]=1;
    44         }
    45 #ifdef debug
    46         F(i,1,5) printf("%d %d
    ",a[i],b[i]);
    47 #endif
    48         int ans=0;
    49         rep(i,4){
    50             int mx=0,now=0;
    51             F(j,1,15){
    52                 now=now+have[i][j]-have[i][max(j-5,0)];
    53                 mx=max(mx,now);
    54             }
    55             ans=max(ans,mx);
    56         }
    57         printf("%d
    ",5-ans);
    58     }
    59     return 0;
    60 }
    View Code

    B

      一开始看错题了[捂脸熊]

      其实就是问有多少种情况下选出两个字符串你能赢。

      容易发现赢的情况是:两个字符串完全相同;或者两个字符串长度和为奇数。第一种情况只需一次B操作就赢了……第二种情况只要努力拿短的那个,最后一个肯定是你的。

      那么记录一下奇数长度和偶数长度的字符串有多少个,以及每个字符串有多少个与它相同(map大法吼!其实map存的是一个pair……first是key,second就是val)

      然后组合数算一下就好了。(然而蒟蒻在快结束的时候发现记录「有多少个奇/偶长度的字符串」的变量用的是int……而不是像ans一样用的是LL……感觉乘的时候要爆炸啊,果断重交了一发,分数&rank瞬间就下来了……QAQ(不过没有FST&被hack应该还是算赚了吧)

     1 //BestCoder #41 B
     2 #include<map>
     3 #include<string>
     4 #include<vector>
     5 #include<cstdio>
     6 #include<cstring>
     7 #include<cstdlib>
     8 #include<iostream>
     9 #include<algorithm>
    10 #define rep(i,n) for(int i=0;i<n;++i)
    11 #define F(i,j,n) for(int i=j;i<=n;++i)
    12 #define D(i,j,n) for(int i=j;i>=n;--i)
    13 #define pb push_back
    14 using namespace std;
    15 inline int getint(){
    16     int v=0,sign=1; char ch=getchar();
    17     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
    18     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
    19     return v*sign;
    20 }
    21 const int N=1e5+10,INF=~0u>>2;
    22 typedef long long LL;
    23 /******************tamplate*********************/
    24 map<string,int>s;
    25 LL gcd(LL a,LL b){return b ? gcd(b,a%b) : a;}
    26 string s1;
    27 int main(){
    28 #ifndef ONLINE_JUDGE
    29     freopen("B.in","r",stdin);
    30     freopen("B.out","w",stdout);
    31 #endif
    32     int T=getint();
    33     while(T--){
    34         s.clear();
    35         LL cnt0=0,cnt1=0;
    36         LL n=getint();
    37         F(i,1,n){
    38             cin >>s1;
    39             if (s1.length()&1) cnt1++;
    40             else cnt0++;
    41             if (s.find(s1)!=s.end()) s[s1]=s[s1]+1;
    42             else s[s1]=1;
    43         }
    44         LL fz=(LL)cnt0*cnt1,fm=n*(n-1)/2;
    45         for(map<string,int>::iterator it=s.begin();it!=s.end();it++){
    46             LL v=it->second;
    47             fz+=v*(v-1)/2;
    48         }
    49         LL d=gcd(fz,fm);
    50         printf("%lld/%lld
    ",fz/d,fm/d);
    51     }
    52     return 0;
    53 }
    View Code

    C

      其实有一道题跟它是很相似的QAQ  【BZOJ】【3612】【HEOI 2014】平衡

      然而蒟蒻没有想到……

      并且这题卡空间!但是又由于有一些特殊性质,可以优化= =

      其实,每个数最多只能拆分成$O(sqrt{n})$个数,因为有$frac{x*(x+1)}{2}=n ightarrow x=2*sqrt{n}$

      所以其实在转移的时候,i-j 不会很远……所以之前很多的计算结果都不用保留了……所以?滚动数组!

     1 //BestCoder #41 C
     2 #include<cmath>
     3 #include<vector>
     4 #include<cstdio>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<iostream>
     8 #include<algorithm>
     9 #define rep(i,n) for(int i=0;i<n;++i)
    10 #define F(i,j,n) for(int i=j;i<=n;++i)
    11 #define D(i,j,n) for(int i=j;i>=n;--i)
    12 #define pb push_back
    13 using namespace std;
    14 inline int getint(){
    15     int v=0,sign=1; char ch=getchar();
    16     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
    17     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
    18     return v*sign;
    19 }
    20 const int N=1e5+10,INF=~0u>>2,mod=998244353;
    21 typedef long long LL;
    22 /******************tamplate*********************/
    23 int f[2000][640];
    24 int main(){
    25 #ifndef ONLINE_JUDGE
    26     freopen("C.in","r",stdin);
    27     freopen("C.out","w",stdout);
    28 #endif
    29     int T=getint(),n,c,l,r;
    30     f[0][0]=1;
    31     while(T--){
    32         n=getint(); c=getint(); l=getint()-c; r=getint()-c;
    33         LL ans=l==0; if (r==n) ans--;
    34         F(i,1,r){
    35             int now=i%1000;
    36             memset(f[now],0,sizeof f[now]);
    37             f[now][1]=1;
    38             for(int j=2;j*(j+1)/2<=i;j++){
    39                 int fa=now-j;
    40                 if (fa<0) fa+=1000;
    41                 f[now][j] = f[fa][j]+f[fa][j-1];
    42                 if (f[now][j]>=mod) f[now][j]-=mod;
    43             }
    44             if (i>=l)
    45                 for(int j=0;j*(j+1)/2<=i;j++){
    46                     ans+=f[now][j];
    47                     if (ans>=mod) ans-=mod;
    48                 }
    49         }
    50         printf("%lld
    ",ans);
    51     }
    52     return 0;
    53 }
    View Code

    D

      SXBK的数学题>_>当然是果断弃疗啊……

      

  • 相关阅读:
    Spring学习,初识Spring
    Spring学习整理
    表单验证一些思考
    为什么要使用mybaits
    JDBC缺点分析
    Java 学习笔记提高篇
    Java基础学习笔记(四)
    Java基础学习笔记(三)
    Java学习笔记(二)
    centos7运行级别和图形界面相关操作
  • 原文地址:https://www.cnblogs.com/Tunix/p/4509343.html
Copyright © 2020-2023  润新知