2019年湘潭大学新生趣味程序设计竞赛

整场比赛都是一些数学题和构造思维题。比较适合锻炼自己逻辑思维能力

G:

一个边长n和m的矩形光滑平面,其边分别平行于坐标走轴,一个小球(视为一个质点),从左上角沿45度方向弹出,小球遇到平面的边时会发生完全弹性碰撞(入射角等于出射角)。

请问小球在碰撞多少次边以后能到达右下角?

这个结论如果有会证明的请在这个博客下留言~感激!!!

结论: 

首先对 m 和 n 进行化简(利用gcd) ,当 m 和 n 都是奇数的时候可以弹到右下角,需要 m + n - 2 次

 1 #include <math.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <iostream>
 5 #include <algorithm>
 6 #include <string>
 7 #include <string.h>
 8 #include <vector>
 9 #include <map>
10 #include <stack>
11 #include <set>
12 #include <queue>
13 
14 #define LL long long
15 #define INF 0x3f3f3f3f
16 #define ls nod<<1
17 #define rs (nod<<1)+1
18 
19 const int maxn = 5e5 + 10;
20 const LL MOD = 998244353;
21 
22 template<class T>inline void read(T &res)
23 {
24     char c;T flag=1;
25     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
26     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
27 }
28 
29 
30 int main(){
31     int T;
32     scanf("%d",&T);
33     while(T--){
34         int n,m;
35         scanf("%d%d",&n,&m);
36         int x=std::__gcd(n,m);
37         n/=x,m/=x;
38         if(n%2==1 && m%2==1)printf("%d
",(n + m - 2));
39         else puts("-1");
40     }
41     return 0;
42 }
Ackerman

H:

因为 n 的范围的限制所以我们可以全部都使用没有次数限制的字符进行构造。

首先就都用单独的一个字符去构造回文串,然后其余的就让其他字符随机出现就好了

 1 #include <math.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <iostream>
 5 #include <algorithm>
 6 #include <string>
 7 #include <string.h>
 8 #include <vector>
 9 #include <map>
10 #include <stack>
11 #include <set>
12 #include <queue>
13 
14 #define LL long long
15 #define INF 0x3f3f3f3f
16 #define ls nod<<1
17 #define rs (nod<<1)+1
18 
19 const int maxn = 5e5 + 10;
20 const LL MOD = 998244353;
21 
22 template<class T>inline void read(T &res)
23 {
24     char c;T flag=1;
25     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
26     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
27 }
28 
29 int vis[30];
30 std::vector<char> vec;
31 char ch[2];
32 
33 
34 int main() {
35     int t;
36     scanf("%d",&t);
37     while (t--) {
38         memset(vis,0, sizeof(vis));
39         vec.clear();
40         int n,x,y,len;
41         scanf("%d%d%d%d",&n,&len,&x,&y);
42         for (int i = 1;i <= n;i++) {
43             scanf("%s %d",ch,&y);
44             vis[ch[0]-'a'] = 1;
45         }
46         for (int i = 0;i < 26;i++)
47             if (!vis[i])
48                 vec.push_back(i+'a');
49         for (int i = 1;i < x;i++)
50             printf("%c",vec[0]);
51         int pos = 0;
52         len -= x-1;
53         while (len--) {
54             printf("%c",vec[pos]);
55             pos++;
56             if (pos == vec.size())
57                 pos = 0;
58         }
59         printf("
");
60     }
61 }
Ackerman

J:

给定一个整数A。
求是否存在两个整数B,C使得长度为A,B,C的三条边可以组成一个直角三角形。

 1 #include <math.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <iostream>
 5 #include <algorithm>
 6 #include <string>
 7 #include <string.h>
 8 #include <vector>
 9 #include <map>
10 #include <stack>
11 #include <set>
12 #include <queue>
13 
14 #define LL long long
15 #define INF 0x3f3f3f3f
16 #define ls nod<<1
17 #define rs (nod<<1)+1
18 
19 const int maxn = 5e5 + 10;
20 const LL MOD = 998244353;
21 
22 template<class T>inline void read(T &res)
23 {
24     char c;T flag=1;
25     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
26     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
27 }
28 
29 
30 int main() {
31     int t;
32     scanf("%d",&t);
33     while (t--) {
34         LL a;
35         scanf("%lld",&a);
36         if ((a * a + 1) % 2 == 0 && (a * a - 1) % 2 == 0) {
37             printf("%lld %lld
",(a * a + 1) / 2,(a * a - 1) / 2);
38         }
39         else
40             printf("%lld %lld
",(a * a / 4) + 1,(a * a / 4) - 1);
41     }
42     return 0;
43 }
Ackerman
原文地址:https://www.cnblogs.com/-Ackerman/p/12175780.html