zoukankan      html  css  js  c++  java
  • 山东省第四届ACM大学生程序设计竞赛解题报告(部分)

    2013年"浪潮杯"山东省第四届ACM大学生程序设计竞赛排名:http://acm.upc.edu.cn/ranklist/

    一、第J题坑爹大水题,模拟一下就行了

    J:Contest Print Server
    【题解】:
      题目大意:输入 n,s,x,y,mod  分别队伍数n,还有一个s生成函数 s=((s*x)+y)%mod,就是打印机根据要求打印纸张,打印到s时,打印机将重置,生成新的s
    【code】:
      
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <string.h>
     4 using namespace std;
     5 
     6 int main()
     7 {
     8     int t;
     9     scanf("%d",&t);
    10     while(t--)
    11     {
    12         int n,s,x,y,mod,i,p;
    13         char team[30],str[20];
    14         int cnt = 0;
    15         scanf("%d%d%d%d%d",&n,&s,&x,&y,&mod);
    16         for(i=0;i<n;i++)
    17         {
    18             scanf("%s%s%d%s",team,str,&p,str);
    19             while(1)
    20             {
    21                 if(p<=s-cnt)
    22                 {
    23                     cnt+=p;
    24                     printf("%d pages for %s
    ",p,team);
    25                     break;
    26                 }
    27                 else
    28                 {
    29                     printf("%d pages for %s
    ",s-cnt,team);
    30                     s = ((s*x)+y)%mod;
    31                     cnt = 0;
    32                 }
    33             }
    34         }
    35         putchar(10);
    36     }
    37     return 0;
    38 }
    View Code

    二、第I题概率DP问题

    I:The number of steps
    【题解】:
          1
         /  
       2 —  3
      /    / 
    4 — 5 — 6
    输入概率:a b c d e 分别表示:
      例如:
         1
        a/     只有左右孩子的就是概率a、b 
         
                  c — 3 
                     d / e    有左右孩子并且有左兄弟  概率分别为 c、d、e
     
         — 5  如果只有左兄弟的话概率为 1
      
      只有以上这三种情况:
        如果f(i)表示第i步达到目的地的概率的话
        结果ans = f(1)*1 + f(2)*2 + f(3)*3 + ....+f(n)*n
    【code】:
     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 
     6 double dp[100][50][50];
     7 int main()
     8 {
     9     int n;
    10     while(~scanf("%d",&n)&&n)
    11     {
    12         double a,b,c,d,e;
    13         scanf("%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e);
    14         memset(dp,0,sizeof(dp));
    15         dp[0][1][1] = 1;
    16         int i,j,k;
    17         for(k=1;k<=(n-1)*2;k++)
    18         {
    19             for(i=1;i<=n;i++)
    20             {
    21                 for(j=1;j<=i;j++)
    22                 {
    23                     if(j-1<1&&i+1<=n&&j+1<=n)
    24                     {
    25                         dp[k][i+1][j] += dp[k-1][i][j]*a;
    26                         dp[k][i+1][j+1] += dp[k-1][i][j]*b;
    27                     }
    28                     else if(j-1>=1&&i+1<=n&&j+1<=n)
    29                     {
    30                         dp[k][i][j-1] += dp[k-1][i][j]*e;
    31                         dp[k][i+1][j] += dp[k-1][i][j]*c;
    32                         dp[k][i+1][j+1] += dp[k-1][i][j]*d;
    33                     }
    34                     else if(j-1>=1&&i==n)
    35                     {
    36                         dp[k][i][j-1] += dp[k-1][i][j];
    37                     }
    38                 }
    39             }
    40         }
    41         double res = 0;
    42         for(i=1;i<=2*(n-1);i++)
    43         {
    44             res+=dp[i][n][1]*i;
    45         }
    46         printf("%.2lf
    ",res);
    47     }
    48     return 0;
    49 }
    View Code

    三、第A题,向量旋转

    A - Problem A:Rescue The Princess
    【题解】:
    给你平面上两个点A、B求点C,是的A、B、C逆时针成等边三角形
    向量的旋转:
    【code1】:
     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 
     6 double xx1,yy1,xx2,yy2;  
     7   
     8 int main()  
     9 {  
    10     int T;  
    11     scanf("%d",&T);  
    12     while (T--)  
    13     {  
    14         scanf("%lf%lf%lf%lf",&xx1,&yy1,&xx2,&yy2);  
    15         double tx = xx2 - xx1;  
    16         double ty = yy2 - yy1;  
    17   
    18         double x = tx*(1.0/2.0) - ty*(sqrt(3.0)/2.0) + xx1;  
    19         double y = ty*(1.0/2.0) + tx*(sqrt(3.0)/2.0) + yy1;  
    20         printf("(%.2lf,%.2lf)
    ",x,y);  
    21     }  
    22     return 0;  
    23 }  
    View Code

    不会向量旋转,直接解方程方法做:

    【code2】:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #define exb 1e-6
      6 #define PI acos(-1.0)
      7 using namespace std;
      8 struct node
      9 {
     10     double x,y;
     11 };
     12 
     13 
     14 double judge(node a ,node b)
     15 {
     16     return (a.x*b.y-a.y*b.x);
     17 }
     18 
     19 double dist(double x1,double y1,double x2,double y2)
     20 {
     21     return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
     22 }
     23 
     24 int main()
     25 {
     26     int t;
     27     scanf("%d",&t);
     28     while(t--)
     29     {
     30         double x1,y1,x2,y2;
     31         scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
     32         double xx=(x1+x2)/2.0;
     33         double yy=(y1+y2)/2.0;
     34         double dd=dist(x1,y1,x2,y2);
     35         if(fabs(y1-y2)<exb)
     36         {
     37             double yy1=y1+dd*sin(PI/3.0);
     38             double yy2=y1-dd*sin(PI/3.0);
     39             node ab,ac;
     40             ab.x=x2-x1;
     41             ab.y=y2-y1;
     42             ac.x=xx-x1;
     43             ac.y=yy1-y1;
     44 
     45             if(judge(ab,ac)>0)
     46             {
     47                 printf("(%.2f,%.2f)
    ",xx,yy1);
     48             }
     49             else
     50             {
     51                 printf("(%.2f,%.2f)
    ",xx,yy2);
     52             }
     53         }
     54         else
     55         {
     56             if(fabs(x1-x2)<exb)
     57             {
     58                 double xx1=x1+dd*sin(PI/3.0);
     59                 double xx2=x1-dd*sin(PI/3.0);
     60                 node ab,ac;
     61                 ab.x=x2-x1;
     62                 ab.y=y2-y1;
     63                 ac.x=xx1-x1;
     64                 ac.y=yy-y1;
     65                 if(judge(ab,ac)>0)
     66                 {
     67                     printf("(%.2f,%.2f)
    ",xx1,yy);
     68                 }
     69                 else
     70                 {
     71                     printf("(%.2f,%.2f)
    ",xx2,yy);
     72                 }
     73             }
     74             else
     75             {
     76                 double k=-(x1-x2)/(y1-y2);
     77                 double pp=atan(k);
     78                 if(pp>PI/2.0)
     79                 pp=PI-pp;
     80                 k=tan(pp);
     81                 double b=yy-(k*xx);
     82                 double dd1=dd*sin(PI/3.0);
     83                 double xx1=sqrt(dd1*dd1/(k*k+1.0));
     84                 double yy1=k*xx1;
     85                 double xx2=-sqrt(dd1*dd1/(k*k+1.0));
     86                 double yy2=k*xx2;
     87                 node ab,ac;
     88                 ab.x=x2-x1;
     89                 ab.y=y2-y1;
     90                 ac.x=xx+xx1-x1;
     91                 ac.y=yy+yy1-y1;
     92                 if(judge(ab,ac)>0)
     93                 {
     94                 printf("(%.2f,%.2f)
    ",xx+xx1,yy+yy1);
     95                 }
     96                 else
     97                 printf("(%.2f,%.2f)
    ",xx+xx2,yy+yy2);
     98             }
     99         }
    100     }
    101     return 0;
    102 }
    View Code

    四、第B题,听说可以暴力BFS过,我们队用的 强连通分量+缩点重构图+拓扑排序

    Problem B:Thrall’s Dream

    【题解】:
      给定n个点,m条有向边,求解任意两点是否可达。也就是 u->v  or  v->u 问题
    【code】:
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #define N 2005
      5 #define M 10005
      6 using namespace std;
      7 struct edges
      8 {
      9     int u,v,next;
     10 };
     11 edges mye[M];
     12 edges cj[M];
     13 int head[N];
     14 int myhead[N];
     15 int cnt;
     16 int cntcnt;
     17 int cc,gg;
     18 int dfn[N],low[N],Belong[N],Stap[N];
     19 bool ff[N];
     20 int visitNum,ct,Stop;
     21 bool flag[N];
     22 int id[N],od[N];
     23 void addEdge(int x,int y)
     24 {
     25     mye[cnt].u=x;
     26     mye[cnt].v=y;
     27     mye[cnt].next=head[x];
     28     head[x]=cnt++;
     29 }
     30 
     31 void Add(int x,int y)
     32 {
     33     cj[cntcnt].u=x;
     34     cj[cntcnt].v=y;
     35     cj[cntcnt].next=myhead[x];
     36     myhead[x]=cntcnt++;
     37 }
     38 
     39 int n,m;
     40 void init()
     41 {
     42     scanf("%d%d",&n,&m);
     43     memset(head,-1,sizeof(head));
     44     memset(myhead,-1,sizeof(myhead));
     45     cnt=1;
     46     cntcnt=1;
     47     for(int i=0;i<m;i++)
     48     {
     49         int x,y;
     50         scanf("%d%d",&x,&y);
     51         addEdge(x,y);
     52     }
     53     memset(dfn,0,sizeof(dfn));
     54     memset(low,0,sizeof(low));
     55     memset(Belong,0,sizeof(Belong));
     56     memset(Stap,0,sizeof(Stap));
     57     memset(flag,false,sizeof(flag));
     58     memset(id,0,sizeof(id));
     59     memset(od,0,sizeof(od));
     60 
     61 }
     62 
     63 void tarjan(int i)
     64 {
     65     int y;
     66     Stap[++Stop]=i;
     67     flag[i]=true;
     68     dfn[i]=low[i]=++visitNum;
     69     for(int j=head[i];j!=-1;j=mye[j].next)
     70     {
     71         y=mye[j].v;
     72         if(!dfn[y])
     73         {
     74             flag[y]=true;
     75             tarjan(y);
     76             low[i]=min(low[i],low[y]);
     77         }
     78         else if(flag[y])
     79         low[i]=min(low[i],dfn[y]);
     80     }
     81     if(low[i]==dfn[i])
     82     {
     83         ct++;
     84         do
     85         {
     86             y=Stap[Stop--];
     87             Belong[y]=ct;
     88             flag[y]=false;
     89         }while(y!=i);
     90     }
     91 }
     92 
     93 void dfs(int x,int len)
     94 {
     95     if(myhead[x]==-1 || len>=ct)
     96     {
     97         if(len>gg)
     98         gg=len;
     99         return;
    100     }
    101     for(int i=myhead[x];i!=-1;i=cj[i].next)
    102     {
    103         int y=cj[i].v;
    104         if(!ff[y])
    105         {
    106             ff[y]=true;
    107             dfs(y,len+1);
    108             ff[y]=false;
    109         }
    110     }
    111 }
    112 void solve()
    113 {
    114     visitNum=ct=Stop=0;
    115     for(int i=1;i<=n;i++)
    116     {
    117         if(!dfn[i])
    118         tarjan(i);
    119     }
    120     if(ct==1)
    121     {
    122         printf("Case %d: Kalimdor is just ahead
    ",cc++);
    123         return;
    124     }
    125     for(int i=1;i<=n;i++)
    126     {
    127         for(int j=head[i];j!=-1;j=mye[j].next)
    128         {
    129             int y=mye[j].v;
    130             int u=Belong[i];
    131             int v=Belong[y];
    132             if(u!=v)
    133             {
    134                 od[u]++;
    135                 id[v]++;
    136                 Add(u,v);
    137             }
    138         }
    139     }
    140     int ans1=0,ans2=0;
    141     int temp=0;
    142     for(int i=1;i<=ct;i++)
    143     {
    144         if(od[i]==0)
    145         {
    146             ans1++;
    147         }
    148         if(id[i]==0)
    149         {
    150             ans2++;
    151             temp=i;
    152         }
    153     }
    154     if(ans1>1 || ans2>1)
    155     {
    156          printf("Case %d: The Burning Shadow consume us all
    ",cc++);
    157          return;
    158     }
    159     memset(ff,false,sizeof(ff));
    160     gg=0;
    161     dfs(temp,1);
    162     if(gg!=ct)
    163     {
    164         printf("Case %d: The Burning Shadow consume us all
    ",cc++);
    165 
    166     }
    167     else
    168     {
    169         printf("Case %d: Kalimdor is just ahead
    ",cc++);
    170     }
    171     return;
    172 }
    173 int main()
    174 {
    175     int t;
    176     scanf("%d",&t);
    177     cc=1;
    178     while(t--)
    179     {
    180         init();
    181         solve();
    182     }
    183     return 0;
    184 }
    View Code

    五、F题

    Problem F:Alice and Bob

    【题解】:

    给出一个多项式:(a0*x^(2^0)+1) * (a1 * x^(2^1)+1)*.......*(an-1 * x^(2^(n-1))+1)

    输入P,求X^p 前边的系数。

    【code】:

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 int a[10086];
     6 int main()
     7 {
     8     long long sb,p;
     9     int t;
    10     int n;
    11     int q;
    12     while(scanf("%d",&t)!=EOF)
    13     {
    14         while(t--)
    15         {
    16             scanf("%d",&n);
    17             int i;
    18             for(i=0;i<n;i++)
    19             {
    20                 scanf("%d",&a[i]);
    21             }
    22             scanf("%d",&q);
    23             while(q--)
    24             {
    25                 scanf("%lld",&p);
    26                 long long sb=1;
    27                 for(i=0;i<n&&p!=0;i++)
    28                 {
    29                     if(p%2==1)
    30                     {
    31                         sb*=a[i];
    32                         sb%=2012;
    33                     }
    34                     p/=2;
    35                 }
    36                 if(p==0)
    37                     printf("%lld
    ",sb);
    38                 else
    39                     printf("0
    ");
    40             }
    41         }
    42     }
    43     return 0;
    44 }
    View Code

    六:E题
    Problem E:Mountain Subsequences

    【code】:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <string.h>
     4 using namespace std;
     5 char sb[100086];
     6 int dp[100086];
     7 int ha[30];
     8 int main()
     9 {
    10     int n;
    11     while(scanf("%d",&n)!=EOF)
    12     {
    13         int i,j,x;
    14         long long max,s;
    15         scanf("%s",sb);
    16         memset(ha,0,sizeof(ha));
    17         for(i=0;i<n;i++)
    18         {
    19             x=sb[i]-'a';
    20             dp[i]=0;
    21             for(j=0;j<x;j++)
    22             {
    23                 dp[i]+=ha[j];
    24                 dp[i]%=2012;
    25             }
    26             ha[x]+=dp[i]+1;
    27             ha[x]%=2012;
    28         }
    29       /*  for(i=n-1;i>=0;i--)
    30         {
    31             printf("%lld ",dp[i]);
    32         }*/
    33        // printf("
    ");
    34         max=0;
    35         memset(ha,0,sizeof(ha));
    36         for(i=n-1;i>=0;i--)
    37         {
    38             x=sb[i]-'a';
    39             s=0;
    40             for(j=0;j<x;j++)
    41             {
    42                 s+=ha[j];
    43                 s%=2012;
    44             }
    45             ha[x]+=s+1;
    46             ha[x]%=2012;
    47             max+=s*dp[i];
    48             max%=2012;
    49            // printf("%lld ",s);
    50         }
    51         //printf("
    ");
    52         printf("%lld
    ",max);
    53     }
    54     return 0;
    55 }
    View Code

     七、H题

    Problem H:Boring Counting

    题解地址:http://www.cnblogs.com/crazyapple/p/3259648.html

  • 相关阅读:
    ASP.NET 2.0的页面缓存功能介绍
    第五课 主定理
    HDU 1051 Wooden Sticks
    一行代码让浏览器变编辑器
    算法概论习题1001Forest
    第七课 寻找强连通分量
    8223. Tiling a Grid With Dominoes
    迷宫
    第八课 最小生成树之Kruskal
    解决 Ubuntu 12.04 无法调节屏幕亮度的问题
  • 原文地址:https://www.cnblogs.com/crazyapple/p/3256803.html
Copyright © 2011-2022 走看看