zoukankan      html  css  js  c++  java
  • BestCoder Round #41------>

    现在才补上,主要是第三题看到神奇代码:

    A:只能说真的好题,我写的很复杂,开始的时候没发现其实可以改变相对顺序,结果。。。

    思路(请忽视代码吧!写的太乱,另外模拟题一直是我最大的不足

    有5个,如果我们全排列所有的话,生成5!=120中,

    对一种判断的方法是固定一个数,我们可以生成合法序列的一种,然后跟原来数列对比。

    这里还要考虑10 11 12 13 1这种排列方式。找到最优解。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<string.h>
     5 #include<string>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<vector>
    10 
    11 #define N 123456
    12 #define inf 0x3f3f3f
    13 using namespace std;
    14 typedef long long ll;
    15 
    16 
    17 string ss[5];
    18 
    19 int a[6];
    20 int b[6];
    21 
    22 
    23 int main()
    24 {
    25     int T;
    26     scanf("%d",&T);
    27 
    28     while (T--)
    29     {
    30         for (int i=0;i<5;i++) cin>>ss[i];
    31         int sxbk=123;
    32         sort(ss,ss+5);
    33 
    34         do
    35         {
    36         for (int i=0;i<5;i++)
    37         {
    38         if    (ss[i][0]=='A')   a[i]=100;
    39         else  if (ss[i][0]=='B') a[i]=200;
    40         else  if (ss[i][0]=='C') a[i]=300;
    41         else  if (ss[i][0]=='D') a[i]=400;
    42         int m=ss[i].size();
    43 
    44         if (m==2) a[i]+=ss[i][1]-'0';
    45         else a[i]+=(ss[i][1]-'0')*10+ss[i][2]-'0';
    46         }
    47 
    48         for (int i=0;i<5;i++)
    49         {
    50             b[i]=a[i]%100;
    51             int wei=a[i]/100;
    52             for (int j=i-1;j>=0;j--)
    53             {
    54                 b[j]=b[i]-1;
    55                 if (b[j]==0) b[j]=1;
    56             }
    57 
    58             for (int j=i+1;j<5;j++)
    59             {
    60                 b[j]=b[j-1]+1;
    61                 if (b[j]==14) b[j]=1;
    62             }
    63 
    64             int flag=0;
    65             for (int j=0;j<5;j++)
    66             {
    67                 if (b[j]==13&&j<3) flag=1;
    68                 if (b[j]==1&&!(j==0||j==4) ) flag=1;
    69             }
    70 
    71 
    72             if (flag) continue;
    73 
    74             int tmp=0;
    75             for (int j=0;j<5;j++) {
    76              b[j]+=wei*100;
    77              if (a[j]!=b[j]) tmp++;
    78             }
    79             sxbk=min(sxbk,tmp);
    80            }
    81         } while (next_permutation(ss,ss+5));
    82         printf("%d
    ",sxbk);
    83     }
    84     return  0;
    85 }
    View Code

    B,写下A题没多少时间了,忘记考虑字串相等也是输的情况。

    所以就是简单的判断奇数偶数,然后用map 判断有多少个完全相等的字串

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<string.h>
     5 #include<string>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<vector>
    10 
    11 #define N 123456
    12 #define inf 0x3f3f3f
    13 using namespace std;
    14 typedef long long ll;
    15 
    16 int  a[23456];
    17 
    18 map<string,int>mp;
    19 string ss;
    20 
    21 int gcd(int aa,int bb)
    22 {
    23     if (aa==0) return 1;
    24     if (bb==0) return aa;
    25     return gcd(bb,aa%bb);
    26 }
    27 
    28 
    29 int main()
    30 {
    31     int T;
    32     scanf("%d",&T);
    33     while (T--)
    34     {
    35     int n;
    36     scanf("%d",&n);
    37     mp.clear();
    38 
    39     int jishu,ou;
    40     jishu=ou=0;
    41 
    42     for (int i=1;i<=n;i++)
    43     {
    44            cin>>ss;
    45            a[i]=ss.size();
    46            if (a[i]&1) jishu ++;
    47            else    ou++;
    48            mp[ss]++;
    49      }
    50 
    51      int  xx=n*(n-1)/2;
    52 
    53      int    yy=jishu*ou;
    54 
    55      map<string,int>::iterator it;
    56      for ( it=mp.begin();it!=mp.end();it++){
    57         int tmp=it->second;
    58         yy+=tmp*(tmp-1)/2;
    59      }
    60 
    61 
    62      int tt=gcd(yy,xx);
    63     // if (yy==0) tt=1,xx=1;
    64 
    65      printf("%d/%d
    ",yy/tt,xx/tt);
    66      }
    67     return  0;
    68 }
    View Code

    C:

    ------------------------------------------分----------------------------------------------隔--------------------------------------线

    这道题赛后补了好久,不能跟上代码的思维度了。

    先丢AC代码:

     1 #include<iostream>
     2 #include<string.h>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<string>
     6 #include<vector>
     7 #include<stdio.h>
     8 
     9 using namespace std;
    10 
    11 typedef long long LL;
    12 typedef double DB;
    13 typedef pair<int, int> PII;
    14 typedef vector<int> VI;
    15 const int MX = 100005;
    16 
    17 const int MC = 450;
    18 const int MOD = 998244353;
    19 int f[MX], g[MX];
    20 int *p = f, *q = g;
    21 int s[MX];
    22 
    23 void init() {
    24      int i, j;
    25      p[0] = 1;
    26 
    27         for (i = 1; i < MC; i++) {
    28         for (j = 0; j < MX; j++)  s[j] = (s[j] + p[j]) % MOD;
    29         for (j = 0; j < i;  j++)  q[j] = 0;
    30         for (j = i; j < MX; j++)  q[j] = (p[j - i] + q[j - i]) % MOD;
    31         swap(p, q);
    32         }
    33 
    34     for (j = 1; j < MX; j++) s[j] = (s[j] + s[j - 1]) % MOD;
    35 }
    36 
    37 int main() {
    38 
    39     int tc, n, c, st, en, rlt;
    40 
    41     init();
    42     for (scanf("%d", &tc); tc--; ) {
    43         scanf("%d%d%d%d", &n, &c, &st, &en);
    44         rlt = s[en - c];
    45         cout<<s[en-c]<<" "<<s[st-c]<<endl;
    46         if (st > c) rlt = (rlt + MOD - s[st - c - 1]) % MOD;
    47        // printf("%d
    ", rlt);
    48     }
    49     return 0;
    50 }
    View Code

    然后是我转换DP方程的代码:

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<math.h>
     5 
     6 using namespace std;
     7 const int MC=448;
     8 const int MX=100001;
     9 const int MOD= 998244353;
    10 
    11 int s[MX];
    12 int dp[MC][MX];//表示 用多少个数,构成和为MX 的方案数
    13 
    14 void init()
    15 {
    16    dp[0][0]=1;
    17    
    18    
    19    
    20    for (int i=1;i<MC;i++)  {
    21    for (int j=0;j<MX;j++)  s[j]=(s[j]+dp[i-1][j])%MOD;//s[j]表示组成和为j的方案数,不管有多少个数。
    22    for (int j=i;j<MX;j++)  dp[i][j]=(dp[i][j-i]+dp[i-1][j-i])%MOD;// 太神奇这里这个方程
    23    //这个转移方程的意思是:类似01背包,dp[i-1][j-i]表示再加入i这个points,dp[i][j-i]表示不懂
    24    //可能表示一种转移即dp[i][j-i]的方案同样可以构成dp[i][j].
    25    //希望这里能有解释一下。
    //BC题解有:
    //转移的时候,要么把之前选择的每一个数增加一,要么在把之前选择的每一个数都增加一个基础上,再新加入一个当前大小为1的数。
    26    }
    27 
    28    for (int j=1;j<MX;j++) s[j]=(s[j]+s[j-1])%MOD;//前缀和,s[i]表示构成1-i所有的方案数
    29 }
    30 
    31 int main()
    32 {
    33    int T;
    34    scanf("%d",&T);
    35    init();
    36    while (T--)
    37    {
    38      int n,c,l,r;
    39      scanf("%d%d%d%d",&n,&c,&l,&r);
    40      int ans=s[r-c];
    41      
    42      if (l>c) ans=(ans+MOD-s[l-c-1])%MOD;
    43      printf("%d
    ",ans);
    44    }
    45    return 0;
    46 }

    本来第二个代码也可以O(nsqrt(n)),但是爆了空间,必须剩下空间。

    思路:都是先预处理出S【I】表示生成1-i所有的方案数。

    然后减减就可以了。

    INIT部分;在代码中,希望能解释代码中我的疑问,

  • 相关阅读:
    洛谷 P1725 琪露诺 题解
    洛谷 P1714 切蛋糕 题解
    洛谷 P1352 没有上司的舞会 题解
    洛谷 P1194 买礼物 题解
    洛谷 P2872 [USACO07DEC]道路建设Building Roads 题解
    OpenCV之头文件分析
    电路学习之二极管(一)
    二极管学习(一)
    STL之vetor 排序
    小波分析(二)
  • 原文地址:https://www.cnblogs.com/forgot93/p/4520765.html
Copyright © 2011-2022 走看看