• 2015 Multi-University Training Contest 9


    1001 Expression

    式子不好推啊。见官方题解。 

    式子知道就方便了。处理好组合数和阶乘。

    按区间长度从小到大递推完就好。

     1 # include <iostream>
     2 # include <cstdio>
     3 # include <cstring>
     4 using namespace std;
     5 # define maxn 105
     6 typedef long long LL;
     7 const LL mod=1e9+7;
     8 LL fac[maxn]={1},C[maxn][maxn];
     9 LL a[maxn],dp[maxn][maxn];
    10 char op[maxn];
    11 
    12 int main(void)
    13 {
    14     for(int i=1;i<maxn;i++) fac[i]=(fac[i-1]*(LL)i)%mod;
    15     for(int i=0;i<maxn;i++) C[i][0]=(LL)1;
    16     for(int i=1;i<maxn;i++)
    17         for(int j=1;j<=i;j++)
    18             C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
    19     int n;
    20     while(~scanf("%d",&n))
    21     {
    22         memset(dp,0,sizeof(dp));
    23         for(int i=1;i<=n;i++) scanf("%I64d",a+i);
    24         scanf("%s",op+1);
    25         for(int i=1;i<=n;i++) dp[i][i]=a[i];
    26         for(int len=2;len<=n;len++)
    27         {
    28             for(int s=1;s+len-1<=n;s++)
    29             {
    30                 for(int m=s;m<s+len-1;m++)
    31                 {
    32                     LL tem;
    33                     if(op[m]=='*') tem=dp[s][m]*dp[m+1][s+len-1];
    34                     else if(op[m]=='+') tem=dp[s][m]*fac[s+len-m-2]+dp[m+1][s+len-1]*fac[m-s];
    35                     else tem=dp[s][m]*fac[s+len-m-2]-dp[m+1][s+len-1]*fac[m-s];
    36                     dp[s][s+len-1]+=tem%mod*C[len-2][m-s]%mod;
    37                 }
    38                 dp[s][s+len-1]=(dp[s][s+len-1]%mod+mod)%mod;
    39             }
    40         }
    41         printf("%I64d
    ",dp[1][n]);
    42     }
    43     return 0;
    44 }
    Aguin

    1002 Hack it!

    1003 GCD Tree

    1004 Too Simple

    果然还是图样。置换顺序乘反了。

    比赛wa到底。拿了数据才知道错在哪。 QAQ。

     1 # include <iostream>
     2 # include <cstdio>
     3 # include <cstring>
     4 using namespace std;
     5 typedef long long LL;
     6 const LL mod=1e9+7;
     7 int a[101][101],vis[101];
     8 LL fac[101]={1};
     9 
    10 LL qpow(LL a,int b)
    11 {
    12     LL d=(LL)1,t=a;
    13     while(b)
    14     {
    15         if(b%2) d=(d*t)%mod;
    16         b/=2;
    17         t=(t*t)%mod;
    18     }
    19     return d;
    20 }
    21 
    22 int main(void)
    23 {
    24     for(int i=1;i<=100;i++) fac[i]=(fac[i-1]*LL(i))%mod;
    25     int n,m;
    26     while(~scanf("%d%d",&n,&m))
    27     {
    28         int ok=1,cnt=0;
    29         for(int i=1;i<=m;i++)
    30         {
    31             scanf("%d",&a[i][1]);
    32             if(a[i][1]==-1) cnt++;
    33             else
    34             {
    35                 for(int j=2;j<=n;j++) scanf("%d",&a[i][j]);
    36                 memset(vis,0,sizeof(vis));
    37                 for(int j=1;j<=n;j++) vis[a[i][j]]++;
    38                 for(int j=1;j<=n;j++) if(vis[j]!=1) ok=0;
    39             }
    40         }
    41         if(!cnt) for(int i=1;i<=n;i++)
    42         {
    43             int pos=i;
    44             for(int j=m;j>0;j--) pos=a[j][pos];
    45             if(pos!=i) ok=0;
    46         }
    47         if(!ok) puts("0");
    48         else
    49         {
    50             LL ans=1;
    51             if(cnt) ans=qpow(fac[n],cnt-1);
    52             printf("%I64d
    ",ans);
    53         }
    54     }
    55     return 0;
    56 }
    Aguin

    1005 Arithmetic Sequence

    以每个点为i。处理一下向前向后能延伸的最大距离。

    d1≠d2时。答案为sigma(pre[i]*suf[i])。

    d1=d2时。pre[i]相当于以i为右端点的区间数。答案为sigma(pre[i])。

     1 # include <iostream>
     2 # include <cstdio>
     3 using namespace std;
     4 typedef long long LL;
     5 const int maxn=100100;
     6 int a[maxn],pre[maxn],suf[maxn];
     7 
     8 int main(void)
     9 {
    10     int n,d1,d2;
    11     while(~scanf("%d%d%d",&n,&d1,&d2))
    12     {
    13         for(int i=1;i<=n;i++) scanf("%d",a+i);
    14         pre[1]=1; suf[n]=1;
    15         for(int i=2;i<=n;i++)
    16         {
    17             if(a[i]==a[i-1]+d1) pre[i]=pre[i-1]+1;
    18             else pre[i]=1;
    19         }
    20         for(int i=n-1;i>0;i--)
    21         {
    22             if(a[i]==a[i+1]-d2) suf[i]=suf[i+1]+1;
    23             else suf[i]=1;
    24         }
    25         LL ans=0;
    26         if(d1==d2) for(int i=1;i<=n;i++) ans+=(LL)pre[i];
    27         else for(int i=1;i<=n;i++) ans+=(LL)pre[i]*(LL)suf[i];
    28         printf("%I64d
    ",ans);
    29     }
    30     return 0;
    31 }
    Aguin

    1006 Persistent Link/cut Tree

    1007 Travelling Salesman Problem

    n或者m为奇数时必然能走完。

    全偶数时选择行标加列标为奇数的格子中最小的格子不走。其余都能走。

    (因为是从偶数格子出发到偶数格子终止的。所以不存在只选一个行标加列标为偶数的格子不走。其他格子都走的情况。)

    具体做法是。设选中格子坐标为(i,j)。如果i为奇。可以先走到(i,j-1)。再绕过选中格子。绕到(i,j+2)。就转变为一边为奇数的情况了。

    同理i为偶数先走到(i-1,j)。绕到(i+2,j)。按奇数边的走完。 

    要注意选中格子i==n或者j==m的情况要特判一下。

    【代码丑- -】

      1 # include <iostream>
      2 # include <cstdio>
      3 using namespace std;
      4 # define INF 2147483647
      5 int n,m,map[101][101];
      6 
      7 void Print_char(int len,char c)
      8 {
      9     for(int i=0;i<len;i++) putchar(c);
     10 }
     11 
     12 void ans_print(int x,int y)
     13 {
     14     if((n-x)%2==0)
     15     {
     16         int len=m-y;
     17         for(int i=x;i<n;i+=2)
     18         {
     19             Print_char(len,'R');
     20             putchar('D');
     21             Print_char(len,'L');
     22             putchar('D');
     23         }
     24         Print_char(len,'R');
     25     }
     26     else
     27     {
     28         int len=n-x;
     29         for(int i=y;i<m;i+=2)
     30         {
     31             Print_char(len,'D');
     32             putchar('R');
     33             Print_char(len,'U');
     34             putchar('R');
     35         }
     36         Print_char(len,'D');
     37     }
     38     printf("
    ");
     39     return;
     40 }
     41 
     42 int main(void)
     43 {
     44     while(~scanf("%d%d",&n,&m))
     45     {
     46         int sum=0;
     47         for(int i=1;i<=n;i++)
     48         {
     49             for(int j=1;j<=m;j++)
     50             {
     51                 scanf("%d",&map[i][j]);
     52                 sum+=map[i][j];
     53             }
     54         }
     55         if(n%2||m%2)
     56         {
     57             printf("%d
    ",sum);
     58             ans_print(1,1);
     59             continue;
     60         }
     61         int Min=INF,x,y;
     62         for(int i=1;i<=n;i++)
     63             for(int j=1;j<=m;j++)
     64                 if((i+j)%2==1&&map[i][j]<Min)
     65                     {Min=map[i][j];x=i;y=j;}
     66         printf("%d
    ",sum-Min);
     67         int xx=1,yy=1;
     68         if(x%2==0)
     69         {
     70             while(xx<x-1)
     71             {
     72                 int len=m-yy;
     73                 Print_char(len,'R');
     74                 putchar('D');
     75                 Print_char(len,'L');
     76                 putchar('D');
     77                 xx+=2;
     78             }
     79             while(yy<y)
     80             {
     81                 int len=n-xx;
     82                 Print_char(len,'D');
     83                 putchar('R');
     84                 Print_char(len,'U');
     85                 putchar('R');
     86                 yy+=2;
     87             }
     88             if(x<n)
     89             {
     90                 Print_char(m-yy,'R');
     91                 putchar('D');
     92                 for(int i=m;i>yy;i--)
     93                 {
     94                     if((i-yy)%2) printf("DL");
     95                     else printf("UL");
     96                 }
     97                 putchar('D');
     98                 ans_print(x+2,y);
     99             }
    100             else
    101             {
    102                 putchar('R');
    103                 ans_print(x-1,y+1);
    104             }
    105         }
    106         else
    107         {
    108             while(xx<x)
    109             {
    110                 int len=m-yy;
    111                 Print_char(len,'R');
    112                 putchar('D');
    113                 Print_char(len,'L');
    114                 putchar('D');
    115                 xx+=2;
    116             }
    117             while(yy<y-1)
    118             {
    119                 int len=n-xx;
    120                 Print_char(len,'D');
    121                 putchar('R');
    122                 Print_char(len,'U');
    123                 putchar('R');
    124                 yy+=2;
    125             }
    126             if(y<m)
    127             {
    128                 Print_char(n-x,'D');
    129                 putchar('R');
    130                 for(int i=n;i>xx;i--)
    131                 {
    132                     if((i-xx)%2) printf("RU");
    133                     else printf("LU");
    134                 }
    135                 putchar('R');
    136                 ans_print(x,y+2);
    137             }
    138             else
    139             {
    140                 putchar('D');
    141                 ans_print(x+1,y-1);
    142             }
    143         }
    144     }
    145     return 0;
    146 }
    Aguin

    1008 Goldbach's Conjecture

    1009 Random Inversion Machine

    1010 Sometimes Naive

  • 相关阅读:
    centos7系统中忘记了root管理员账号密码的解决方式
    【python之路48】生成器表达式、推导式
    小米集团信息化中台战略
    分时函数
    函数节流
    JS浮点计算问题
    要转型做前端开发了
    优秀的开发人员和测试人员应有的态度
    C#数组的笔记
    LINQ不包含列表
  • 原文地址:https://www.cnblogs.com/Aguin/p/4740083.html
Copyright © 2020-2023  润新知