2016.10.14【周赛】第二周周赛——打怪升级不按套路 ——题解

A:

A题很简单只要满足两个条件即可

1.abs(a)+abs(b)<=s

2.s-abs(a)-abs(b)是偶数

附AC代码

 1 #include<stdio.h>
 2 int main()
 3 {
 4     int  a,b,s;
 5     scanf("%d%d%d",&a,&b,&s);
 6     if(a<0)
 7         a=-a;
 8     if(b<0)
 9         b=-b;
10      if(a+b<=s&&(s-a-b)%2==0)
11         puts("Yes");
12     else
13        puts("No");
14 
15     return 0;
16 }

 

B:

这题是道简单的贪心,只要排序一下,再从大到小拿走即可,因为数据很小,也可以两个for暴力

附AC代码

 1 #include<stdio.h>
 2 #include<algorithm>
 3 using namespace std;
 4 int main()
 5 {
 6     int  n,i,a[105],sum=0,s=0;
 7     scanf("%d",&n);
 8     for(i=0;i<n;i++)
 9     {
10           scanf("%d",&a[i]);
11           sum+=a[i];
12     }
13     sort(a,a+n);
14     for(i=1;i<=n;i++)
15     {
16         s+=a[n-i];
17         if(s+s>sum)
18             break;
19     }
20     printf("%d\n",i);
21     return 0;
22 }

 

C:这题是道简单的dp,难点在于转化模型

这是其实不难发现这题就是简单台阶模型,我们可以这样看

假设 你目前位于0的位置,然后你一步最大可以跨过m级台阶,这时你两步间留下的没被踩到的阶梯的个数刚好小于m,这和题目要求的模型一模一样。

不难得出转移方程 dp[i]=dp[i-1]+dp[i-2]+……+dp[i-m] ,然后就是上界的问题,由于第n个位置可以种或不种,即第n阶台阶可以跨过去,所以上界应选n+1。最后再注意一下int会溢出,应该使用long long就能AC了

附AC代码

 1 #include<stdio.h>
 2 #include<string.h>
 3 int main()
 4 {
 5     int i,j,n,m;
 6     long long dp[100];
 7     while(scanf("%d%d",&n,&m)!=EOF)
 8     {
 9 
10         memset(dp,0,sizeof(dp));
11         dp[0]=1;
12         for(i=0;i<=n;i++)
13         {
14             for(j=1;j<=m;j++)
15             dp[i+j]+=dp[i];
16         }
17         printf("%I64d\n",dp[n+1]);
18     }
19     return 0;
20 }

 

 

D:

这题是道简单的模拟题,唯一的难点是判断是否能追上,首先我们不难得出地图里路径走到最后一定是形成了各自的循环,考虑到地图的大小我们可以推测猫和老鼠各自的周期肯定小于100,如果他们能相遇的话,时间一定不可能大于公共最小周期,所以设个时间限制100*100,超过这个时间就肯定追不到了(你设得大一点也行,因为时间限制很宽裕,事实上这个值可以设得比10000还小得多)

附AC代码

 1 #include<stdio.h>
 2 #include<string.h>
 3 char Map[15][15];
 4 struct Pos
 5 {
 6     int dir;
 7     int x,y;
 8 
 9 } mouse,cat;
10 
11 Pos move(Pos animal)
12 {
13     int x=animal.x,y=animal.y,dir=animal.dir;
14     if(dir==0&&Map[x-1][y])
15     {
16         animal.x--;
17     }
18     else if(dir==1&&Map[x][y+1])
19     {
20         animal.y++;
21     }
22     else if(dir==2&&Map[x+1][y])
23     {
24         animal.x++;
25     }
26     else if(dir==3&&Map[x][y-1])
27     {
28         animal.y--;
29     }
30     else
31     {
32         animal.dir++;
33     }
34     return animal;
35 }
36 
37 int main()
38 {
39     int n,i,j,t,time;
40     char s[15];
41     scanf("%d",&t);
42     while(t--)
43     {
44         memset(Map,0,sizeof(Map));
45         mouse.dir=0;
46         cat.dir=0;
47         time=0;
48         for(i=1; i<=10; i++)
49         {
50             scanf("%s",&s);
51             for(j=1; j<=10; j++)
52             {
53                 Map[i][j]=(s[j-1]!='*');
54                 if(s[j-1]=='m')
55                 {
56                     mouse.x=i;
57                     mouse.y=j;
58 
59                 }
60                 else if(s[j-1]=='c')
61                 {
62                     cat.x=i;
63                     cat.y=j;
64                 }
65             }
66         }
67         while(1)
68         {
69             mouse.dir%=4;
70             cat.dir%=4;
71             mouse=move(mouse);
72             cat=move(cat);
73             time++;
74             if(time>10000)
75             {
76                 printf("0\n");
77                 break;
78             }
79             if(mouse.x==cat.x&&mouse.y==cat.y)
80             {
81                 printf("%d\n",time);
82                 break;
83             }
84         }
85     }
86     return(0);
87 }

 

E:这题作为压轴大题,复杂度,和难度相比之前的题都有着爆炸式增长,前面之所以有那么多水题,是希望能留够时间给大家做这道题。由于这题数据较大,大家做矩阵乘法法时一定要小心long long的溢出,我写的矩阵乘法是加完再MOD,结果做加法时溢出,导致WA一次。

这题就不附完整的AC代码了,而是给出思路,和部分代码,希望读者能独立的做出来这道超级模板题。

首先先看提示

 从中不难看出杨辉三角的影子

其实矩阵是这样构造的

首先构造齐K次递推方程组 即

然后将方程转化成矩阵

显然有

 

 1 #include<stdio.h>
 2 #include<string.h>
 3 struct matrix
 4 {
 5  long long   m[60][60];/** m的类型注意调整*/
 6 }e,o;
 7 long long c[100][100];
 8 
 9 int main()
10 {
11 
12     int i,n,k,j,m,x,l,f1,f2,a,b,t;
13     long long v[60],temp;
14     matrix T;
15     memset(e.m,0,sizeof(e.m));
16     for(i=0;i<52;i++)
17         e.m[i][i]=1;/**初始化单位阵*/
18     memset(o.m,0,sizeof(o.m));/**初始化零矩阵*/
19     c[0][0]=1;
20     for(i=1;i<=52;i++)
21     {
22         c[i][0]=1;
23         for(j=1;j<=i;j++)
24             c[i][j]=c[i-1][j-1]+c[i-1][j];
25     }
26     scanf("%d",&t);
27     while(t--)
28     {
29         scanf("%d%d%d%d%d%d%d",&f1,&f2,&a,&b,&k,&n,&m);
30         memset(T.m,0,sizeof(T.m));
31         T.m[k][0]=1;
32         for(i=k-1;i>=0;i--)
33         {
34             for(j=0;j<k-i;j++)
35             {
36                 T.m[i][j]=T.m[i+1][j]*a%m;
37             }
38             T.m[i][k-i]=T.m[i+1][k-i-1]*b%m;
39         }
40         for(i=0;i<k;i++)
41         {
42             for(j=0;j<=k-i;j++)
43             {
44                 T.m[i][j]=T.m[i][j]*(c[k-i][j]%m)%m;
45             }
46         }
47         T.m[k+1][0]=1;
48         T.m[k+1][k+1]=1;
49         for(i=0;i<=k+1;i++)
50         {
51             for(j=0;j<=k+1;j++)
52                 printf("%5I64d",T.m[i][j]);
53             puts("");
54         }
55     v[0]=1,temp=1;
56     for(i=1;i<=k;i++)
57     {
58         v[i]=v[i-1]*f1%m;
59     }
60     for(i=k-1;i>=0;i--)
61     {
62         temp=temp*f2%m;
63         v[i]=v[i]*temp%m;
64     }
65     v[k+1]=v[k];
66     matpow(T,n-1,k+2,m,v);
67     }
68     return 0;
69 }

 

posted @ 2016-10-14 18:10  强势围观  阅读(218)  评论(0编辑  收藏  举报