zoukankan      html  css  js  c++  java
  • BestCoder Round #93 ABC

    A:

    题目大意:

    将数组划分成最少的段,每段的数两两不同。

    题解:直接用一个map记录一个数是否出现过,贪心的每次取最多个数就好。


    B:

    题目大意:

    给出一个0-9组成的字符串,问能否删掉K个数字,使得最后形成的数没有前导零且能被3整除。

    题解:

    最后会留下N-K个数,枚举第一个数的位置,然后问题就可以转化为判断同余方程0*x+1*y+2*z = v (mod 3) 是否有解。   其中(x+y+z=K-1  && x<=a && y<=b && z<=c)

    设:

    x = i (mod 3)

    y = j (mod 3)

    z = k (mod 3)

    在[0,2]范围里枚举i,j,k  

    然后可行的条件是:

    1.    i<=a , j <=b , k <=c   

    2.    0*i+1*j+2*k = v (mod 3)

    3.    i+j+k <= K-1

    4.    3*( (a-i)/3+(b-j)/3+(c-k)/3 )+ i+ j + k >= K-1

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <cmath>
     7 #include <map>
     8 using namespace std;
     9 
    10 #define X first
    11 #define Y second
    12 #define N 100010
    13 #define M 500010
    14 
    15 typedef long long ll;
    16 const int INF=1ll<<30;
    17 
    18 char s[N];
    19 int dp[N][3],suf[N][3];
    20 
    21 bool Check(int a,int b,int c,int r,int n)
    22 {
    23     for (int i=0;i<3 && i<=a;i++)
    24     {
    25         for (int j=0;j<3 && j<=b;j++)
    26         {
    27             for (int k=0;k<3 && k<=c;k++)
    28             {
    29                 if (i+j+k>n) continue;
    30                 if ((j+k*2)%3!=r) continue;
    31                 if ((n-i-j-k)%3) continue;
    32                 int t=(a-i)/3+(b-j)/3+(c-k)/3;
    33                 if (3*t>=n-i-j-k) return true;
    34             }
    35         }
    36     }
    37     return false; 
    38 }
    39 
    40 int main()
    41 {
    42     //freopen("in.in","r",stdin);
    43     //freopen("out.out","w",stdout);
    44     
    45     int T,n,K; scanf("%d",&T);
    46     while (T--)
    47     {
    48         scanf("%d%d",&n,&K); 
    49         scanf("%s",s+1);
    50         K=n-K;
    51         if (K==1)
    52         {
    53             bool flag=false;
    54             for (int i=1;i<=n;i++) if ((s[i]-'0')%3==0) flag=true;
    55             puts(flag? "yes":"no");
    56             continue;
    57         }
    58         suf[n+1][0]=suf[n+1][1]=suf[n+1][2]=0;
    59         for (int i=n;i>=1;i--)
    60         {
    61             suf[i][0]=suf[i+1][0];
    62             suf[i][1]=suf[i+1][1];
    63             suf[i][2]=suf[i+1][2];
    64             suf[i][(s[i]-'0')%3]++;
    65         }
    66         bool flag=false;
    67         for (int i=1;i<=n;i++)
    68         {
    69             if (s[i]=='0') continue;
    70             int a=suf[i+1][0],b=suf[i+1][1],c=suf[i+1][2];
    71             
    72             int r=(s[i]-'0')%3,need=r==0? 0:3-r;
    73             if (Check(a,b,c,need,K-1)) flag=true;
    74         }
    75         puts(flag? "yes":"no");
    76     }
    77     
    78     return 0;
    79 }
    View Code

    C:

    由26个小写字母组成长度为n的字符串, 定义一次变化后 字母i会变成a[i], 问一个随机的字符串 变换成自身的期望次数。

    题解:

    首先求出置换环, 因为总共才26个字母,置换环不同的大小最多有6种(1+2+3+4+5+6<26  1+2+3+4+5+6+7>26)。

    设字母i变换fi次变成自身,fi就是它所在置换环大小。  

    一个串变成自身所需的次数就是串内所有字母的fi的最小公倍数。

    所以可以枚举串内有哪些fi, 最多$2^6$ 种情况。

    对于当前枚举的特定的fi集合S, 可以用容斥原理来计算总的次数, 即枚举哪些fi没被用上,  用二项式定理容易证明 两次枚举的复杂度一共是$3^6$

    具体实现看代码:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <vector>
      6 #include <cmath>
      7 #include <queue>
      8 using namespace std;
      9 
     10 #define X first
     11 #define Y second
     12 #define N 100010
     13 #define M 11
     14 
     15 typedef long long ll;
     16 const int Mod=1000000007;
     17 const int INF=1<<30;
     18 
     19 char s[26];
     20 int cnt[27],a[10],b[10];
     21 int pw[27];
     22 bool vis[26];
     23 
     24 int Lcm(int x,int y)
     25 {
     26     int lcm=x*y,tmp;
     27     while (y)
     28     {
     29         tmp=x%y;
     30         x=y,y=tmp;
     31     }
     32     
     33     return lcm/x;
     34 }
     35 
     36 int Power(int x,int P)
     37 {
     38     if (pw[x]) return pw[x];
     39     int res=1,xx=x;
     40     for (;P;P>>=1)
     41     {
     42         if (P&1) res=1ll*res*x%Mod;
     43         x=1ll*x*x%Mod;
     44     }
     45     return pw[xx]=res;
     46 }
     47 
     48 int Solve(int len,int n)
     49 {
     50     //for (int i=0;i<n;i++) cout<<i<<" "<<a[i]<<" "<<b[i]<<endl;
     51     int lim=1<<n,val,cnt,m,t,res=0;
     52     for (int mask1=1;mask1<lim;mask1++)
     53     {
     54         val=1; t=0; 
     55         for (int i=0;i<n;i++) if (mask1&(1<<i)) val=Lcm(val,a[i]),t+=b[i];
     56         cnt=Power(t,len);
     57         for (int mask2=(mask1-1)&mask1;mask2;mask2=(mask2-1)&mask1)
     58         {
     59             int op=1; m=t;
     60             for (int j=0;j<n;j++) if (mask2&(1<<j)) op=-op,m-=b[j]; 
     61             cnt+=op*Power(m,len); cnt%=Mod;
     62         }
     63 
     64         res+=1ll*cnt*val%Mod; res%=Mod;
     65     }
     66     return res<0? res+Mod:res;
     67 }
     68 
     69 int main()
     70 {
     71     //freopen("in.in","r",stdin);
     72     //freopen("out.out","w",stdout);
     73     
     74     int T,len; scanf("%d",&T);
     75     while (T--)
     76     {
     77         scanf("%d%s",&len,s);
     78         memset(vis,0,sizeof(vis));
     79         memset(cnt,0,sizeof(cnt));
     80         memset(pw,0,sizeof(pw));
     81         for (int i=0;i<26;i++)
     82         {
     83             if (!vis[i])
     84             {
     85                 int c=0,x=i;
     86                 do
     87                 {
     88                     c++;    
     89                     x=s[x]-'a';
     90                     vis[x]=true;
     91                 }while (x!=i);
     92                 cnt[c]+=c;
     93             }
     94         }
     95         int n=0;
     96         for (int i=1;i<=26;i++) if (cnt[i]) a[n]=i,b[n++]=cnt[i];
     97         printf("%d
    ",Solve(len,n));
     98     }
     99     return 0;
    100 }
    View Code
  • 相关阅读:
    docker学习笔记
    无法启动此程序,因为计算机中丢失api-ms-win
    pandas, groupby
    Chapter Five, More Than Two Variables: Graphical Multivariate Analysis
    ARIMA, Autoregressive Moving Average
    Chapter Four, Time As a Variable: Time-Series Analysis
    Exponentially Weighted Moving-Average
    KaKs_calculator
    pal2nal
    clustal
  • 原文地址:https://www.cnblogs.com/vb4896/p/6665991.html
Copyright © 2011-2022 走看看