2020牛客NOIP赛前集训营-普及组(第四场)A B C

时间 题目链接

  签到题,还是比较简单的,我们可以将时钟化为分钟,再跟3小时30分钟相加,然后用最后的总分钟数对一天的总分钟数取余,在化为时钟跟分钟;

  看代码:

  

 1 #include <iostream>
 2 #include <cstdio>
 3 
 4 using namespace std;
 5 typedef long long ll;
 6 const int ma = 1e5 + 7;
 7 int n,m,num[ma];
 8 
 9 int main()
10 {
11     int d,m;
12     scanf("%d:%d",&d,&m);
13     n = d * 60 + m + 210;
14     n %= 1440;
15     d = n / 60,m = n % 60;
16     if(d < 10)
17         printf("0");
18     printf("%d:",d);
19     if(m < 10)
20         printf("0");
21     printf("%d",m);
22     return 0;
23 }
View Code

石子 题目链接

  根据题目意思A只能拿走偶数个的石子,B只能拿走奇数个的石子,那么我们就可以考虑对于奇数或者偶数个的石子,A,B会怎么样?

      奇数个的石子:首先对于A来讲,因为A只能拿走偶数个的石子那么A肯定不能将石子拿完,那最后只能被B拿走,那就说明可以不用考虑奇数个的石子了,因为不管怎么样最后肯定是被B拿走最后的石子,就比如有石子13,A分别可以拿2 、4、8、10、12,但是总有奇数留下使得A不能拿完,所以如果有奇数的石子那就可以忽略不计看偶数个的石子了,如果没有偶数个的石子,那肯定是B赢得比赛,因为A一定不可以拿完,直到最后所有的石子堆都变成奇数堆而不能走停止。

      偶数的石子:对于A来讲,因为他是先手所以他可以把一堆全部拿走,或者留下一个更小的偶数,然后后手选择了,后手就可以选择把另一堆的偶数堆变成奇数堆,这样A肯定是赢不了的。比如有两堆的石子,数量分别是2,3.那么A先走的话,有两种选择,一是将选择第一堆,那第一堆就没了,B就可以选择将第二堆全部拿走了,这样B就赢了;第二种就是选择第二堆,那A只能拿走2个,第二堆就剩下1个了,那就剩下两个堆都是奇数堆了,那肯定是B赢了。

  总结:如果有偶数堆的话,只要A没有将全部拿走,那B肯定会将偶数堆变成奇数堆的。如果所有的都是技术堆,那肯定是B赢了,因为A怎么也不可能将奇数堆拿完。所以就只有一种情况A可以赢得比赛,就是只有一个堆并且这个堆的数量为偶数,这样可以让B没法拿走,所以代码就很简单了。

  但是千万要注意这是多组输入!!!我就是没看到要多组输入导致我只得了20分,唉。

  

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <queue>
 4 
 5 using namespace std;
 6 typedef long long ll;
 7 const int ma = 1e5 + 7;
 8 int n,m,num[ma];
 9 
10 int main()
11 {
12     while(scanf("%d",&n) != EOF)
13     {
14         for(int i = 1;i <= n;i++)
15         scanf("%d",num+i);
16     if(n == 1 && !(num[1] & 1))
17         puts("YES");
18     else 
19         puts("NO");
20     }
21     return 0;
22 }
View Code

 

C卡片 题目链接

  有一个正M边形,一个正N边形,让M边形在N边形上走,要求走到跟一开始的一样。那我们就可以分析。M边形走过的路程肯定是N边形周长的倍数,因为要走到跟一开始的一样,那M边形走的路程也是它边长a的倍数,对于M边形来讲,只要有一条边长跟一开始的完全一样就可以了,因为它是正多变形,那刻就可以假设是N边形周长C的x倍,是M边形边长A的y倍,那就是Cx = Ay了,那肯定是要求他们的最小公倍数了,这样他们相等了也就到了跟一开始完全相同的状态了,所以就可以知道要走多少遍N边形。

  看样例1会发现有的点必须要旋转两次才可以,所以这样又不好算了,但是画一下图,你就会发现只有走过的路长为边长a,b的最小公倍数的时候,它就不会一个边要转折两次了,所以我们就只需要求这样点的个数就可以了。

  

 1 #include <bits/stdc++.h>
 2 #include <iostream>
 3 #include <cstdio>
 4 
 5 using namespace std;
 6 typedef long long ll;
 7 const int ma = 1e5 + 7;
 8 const int mod = 1e9 + 7;
 9 ll n,m,k;
10 string s;
11 
12 ll gcd(ll a,ll b)
13 {
14     return a % b ? gcd(b,a%b):b;
15 }
16 int main()
17 {
18     ll a,b;
19     cin >> a >> m >> b >> n;
20     //求最小公倍数
21     ll mul = a * b * n / gcd(a,b * n);
22     // temp 为N边形的圈数
23     ll temp = mul / (b * n);
24     //len为要旋转的总长度,cnt用来计数
25     ll len = temp * n * b,cnt = 0,c ;
26     // num为长度可以化为多少个a
27     ll num = len / a;
28     c = a*b / gcd(a,b);
29     //在总长度中找长度为lcm(a,b)倍数的值。
30     for(int i = 0;i * c < len;i++)
31     {
32         cnt++;
33     }
34     //因为只有不是他们的倍数的点常需要两步走完一个点,也就是讲只要加上这么多个点就可以了。
35     ll ans = num + temp * n - cnt; 
36     cout<<ans<<endl;
37     return 0;
38 }
View Code

 

posted @ 2020-10-26 21:11  好学生就是我  阅读(101)  评论(0编辑  收藏  举报