华东交通大学2017年ACM“双基”程序设计竞赛

大吉大利今晚吃鸡

Problem Description

最近流行吃鸡,那就直接输出一行"Winner winner ,chicken dinner!"(没有双引号)
模板代码:
#include <stdio.h>
int main(){
printf("hello world\n");
return 0;
}

Input

没有输入

Output

输出一行"Winner winner ,chicken dinner!"注意要换行

Sample Output

Winner winner ,chicken dinner!
水题
1 #include <bits/stdc++.h>
2 #define ll long long
3 using namespace std;
4 const int N = 110;
5 
6 int main() {
7     cout << "Winner winner ,chicken dinner!" << endl;
8     return 0;
9 }

 

跳舞

Problem Description

一天YZW参加了学校组织交际舞活动,活动的开始活动方分别给男生和女生从1-n进行编号,按照从小到大顺时针的方式进行男女搭档分配,相同编号的男女组合成一对,例如一号男生与一号女生配对,以此类推。可是YZW对其中一个小姐姐一见钟情,于是机智的他向管理员提出了两种操作
1.在这种情况下,管理员会给出移动的方向和大小,然后所有的男生向着这个方向移动x个位置。2.管理员会把相邻的奇数和偶数位置上的男生互换。
在其中女生的位置是不会变的。可是YZW不知道经过这些Q次操作后,他自己身在何方,能否到达自己喜欢的小姐姐身边。

Input

输入一个T代表T组数据(T<=10),每组输入一个n和q(2≤n≤200000,1≤q≤1000000,其中n为偶数),分别代表有n对男女和有q次操作。
接下来是q行,每一行输入:
1.x代表所有男生移动的位置的大小。同时x>0表示顺时针移动,x<0表示逆时针移动。
2.代表管理员会把相邻的奇数和偶数位置上的男生互换。

Output

输出1号到n号小姐姐配对的分别是几号男生。

Sample Input

1
6 3
1 2
2
1 2

Sample Output

4 3 6 5 2 1
假设n是6:
一开始是1 2 3 4 5 6, 可以看成
1 3 5
2 4 6
只要记录这两列数字的1和2的位置就可以了。
 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N = 110;
 5 
 6 int main() {
 7     int T, n, q;
 8     cin >> T;
 9     while(T--) {
10         cin >> n >> q;
11         int flag, x;
12         int a = 0, b = 0;
13         while(q --) {
14             cin >> flag;
15             if(flag == 1) {
16                 scanf("%d",&x);
17                 a = (n+a-x)%n;  
18                 b = (n+b-x)%n;  
19                 if(x&1) swap(a,b);
20             } else {
21                 a = (a+n-1)%n;  
22                 b = (b+n+1)%n;  
23                 swap(a,b);
24             }
25         }
26         for (int i = 1;i <= n; i ++) {  
27             if (i&1)printf("%d%c",(a+i-1+n)%n+1,(i==n?'\n':' '));  
28             else printf("%d%c",(b+i-1+n)%n+1,(i==n?'\n':' '));  
29         }
30     }
31     return 0;
32 }

 

这是道水题

Problem Description

有两个球在长度为L的直线跑道上运动,两端为墙。0时刻小球a以1m/s的速度从起点向终点运动,t时刻小球b以相同的速度从终点向起点运动。问T时刻两球的距离。这里小球与小球、小球与墙的碰撞均为弹性碰撞,所有过程没有能量损失。

Input

先输入一个q,代表q组数据,然后每组3个整数 L,t,T。
1<=L<=1000;0<=t<=1000;t<=T<=1000;

Output

一个整数,代表答案。

Sample Input

2
10 4 7
8 3 9

Sample Output

0
5

由于速度都相同,所以可以看成他们不会碰撞,相撞时可以直接过去,不会走反方向。
这样两个球走的距离分别是T和T-t
 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N = 110;
 5 
 6 int main() {
 7     int q, t, L , T;
 8     cin >> q;
 9     while(q--) {
10         cin >> L >> t >> T;
11         int a = T, b = T - t;
12         a %= (2*L);
13         b %= (2*L);
14         // printf("%d %d\n",a,b);
15          if(a > L) a = 2*L - a;
16          if(b <= L) b = L - b;
17          else if(b > L) b = b - L;
18          printf("%d\n",abs(a-b));
19     }
20     return 0;
21 }

矩阵

Problem Description

假设你有一个矩阵,有这样的运算A^(n+1) = A^(n)*A (*代表矩阵乘法)
现在已知一个n*n矩阵A,S = A+A^2+A^3+...+A^k,输出S,因为每一个元素太大了,输出的每个元素模10

Input

先输入一个T(T<=10),每组一个n,k(1<=n<=30, k<=1000000)

Output

输出一个矩阵,每个元素模10(行末尾没有多余空格)

Sample Input

1
3 2
0 2 0
0 0 2
0 0 0

Sample Output

0 2 4
0 0 2
0 0 0
矩阵快速幂。
A^1+A^2+A^3+A^4+A^5+A^6可以看成A^3(A^1+A^2+A^3)+A^1+A^2+A^3
A^1+A^2+A^3+A^4+A^5可以看成A^5+A^2(A^1+A^2)+A^1+A^2.
所以dfs一下就可以了。
 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 typedef vector<ll> vec;
 5 typedef vector<vec> mat;
 6 const ll Mod = 10;
 7 ll t, len, k;
 8 int b[33][33];
 9 mat mul(mat &A, mat &B) {
10     mat C(A.size(), vec(B[0].size()));
11     for(int i = 0; i < A.size(); i ++) {
12         for(int k = 0; k < B.size(); k ++) {
13             for(int j = 0; j < B[0].size(); j ++) {
14                 C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % Mod;
15             }
16         }
17     }
18     return C;
19 }
20 mat add(mat A, mat B) {
21     mat C(len, vec(len));
22     for(int i = 0; i < len; i ++) {
23         for(int j = 0; j < len; j ++) {
24             C[i][j] = (A[i][j] + B[i][j]) % Mod;
25         }
26     }
27     return C;
28 }
29 mat pow(mat A, ll n) {
30     mat B(A.size(), vec(A.size()));
31     for(int i = 0; i < A.size(); i ++) {
32         B[i][i] = 1;
33     }
34     while(n > 0) {
35         if(n&1) B = mul(B,A);
36         A = mul(A,A);
37         n >>= 1;
38     }
39     return B;
40 }
41 mat dfs(mat A, ll tmp) {
42     if(tmp == 1) return A;
43     mat B(len, vec(len));
44     mat C(len, vec(len));
45     if(tmp%2 == 0) {
46         B = dfs(A, tmp/2);
47         C = pow(A, tmp/2);
48         return add(mul(B,C), B);
49     } else {
50         B = dfs(A, tmp/2);
51         C = pow(A, tmp/2);
52         return add(pow(A, tmp), add(B, mul(C, B)));
53         //add(pow(A,tmp),add(mul(pow(A,tmp/2),dfs(A,tmp/2)), dfs(A,tmp/2)));
54     }
55 }
56 int main() {
57     
58     cin >> t;
59     while(t--) {
60         cin >> len >> k;
61         mat A(len, vec(len));
62         mat B(len, vec(len));
63         for(int i = 0; i < len; i ++) {
64             for(int j = 0; j < len; j ++) {
65                 cin >> A[i][j];
66                 b[i][j] = A[i][j]%10;
67             }
68         }
69         //B = add(A,A);
70         B = dfs(A, k);
71         for(int i = 0; i < len; i ++) {
72             for(int j = 0; j < len-1; j ++) {
73                 printf("%d ",B[i][j]);
74             }
75             printf("%d\n",B[i][len-1]);
76         }
77     }
78     return 0;
79 }

 

子序列

Problem Description

长度为 n 的序列,把它划分成两段非空的子序列,定义权值为:两段子序列的最大值的差的绝对值。求可能的最大的权值。
数据范围:
2 <= n <= 10^6 , 0 < 序列内的数 <= 10^6 。

Input

第一行输入一个 T,表示有 T 组数据。
接下来有 T 组数据,每组数据的第一行输入一个数 n ,第二行输入 n 个数。

Output

每组数据输出可能的最大的权值。

Sample Input

1
3
1 2 3

Sample Output

2

一列数字分成两份,最他们最大值的差值。用数字保存从 1-i (i<=n) 的最大值和从i-n(1<=i)的最大值,然后求最大差值。

 

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N = 1e6+10;
 5 int a[N], pre[N], sum[N];
 6 int main() {
 7     int T;
 8     cin>> T;
 9     while(T--) {
10         int n;
11         cin >> n;
12         memset(sum, 0, sizeof(sum));
13         memset(pre, 0, sizeof(pre));
14         for(int i = 1; i <= n; i ++) cin >> a[i];
15         for(int i = 1; i <= n; i ++) {
16             sum[i] = max(sum[i-1], a[i]);
17         }
18         for(int i = n; i > 0; i --) {
19             pre[i] = max(pre[i+1], a[i]);
20         }
21         int MAX = -1;
22         for(int i = 2; i <= n; i ++){
23             MAX = max(MAX, abs(pre[i]-sum[i-1]));
24         }
25         printf("%d\n",MAX);
26     }
27     return 0;
28 }

 

MDD的随机数

Problem Description

MDD随机生成了n(n<le5)个随机数x(x<=1e9),
这n个随机数排成一个序列,MDD有q(q<=le5)个询问,
每个询问给你一个a,问你这个序列中有多少个区间的最大公约数不为a

Input

第一行输入一个T,表示T组测试样例
每组样例包含一个n,表示n个随机数
再输入一个Q,表示Q个询问
每个询问输入一个a

Output

每个询问输出有多少个区间的gcd不为a

Sample Input

1
5
1 2 4 4 1
4
1
2
3
4

Sample Output

6
12
15
12
预处理,用map储存最大公约数出现的次数,
 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 map<int,ll>mp;
 5 const int N=1e5+10;
 6 int n,j,t,a,q;
 7 int ans[N],ls[N],vis[N];
 8 void init(){
 9     mp.clear();
10     cin >> n;
11     for(int i = 1;i <= n;i ++) cin >> ans[i];
12     for(int i = 1;i <= n;i ++) {
13         for(vis[i] = ans[i],j = ls[i]=i; j; j=ls[j]-1){
14             vis[j]=__gcd(vis[j],ans[i]);
15         while(ls[j] > 1&& __gcd(ans[i], vis[ls[j]-1]) == __gcd(ans[i], vis[j]))
16             ls[j] = ls[ls[j]-1];
17         mp[vis[j]] += j-ls[j]+1;
18         }
19     }
20 }
21 
22 int main(){
23     cin >> t;
24     while(t--){
25         init();
26         cin >> q;
27         while(q--){
28             cin >> a;
29             ll len = n*(n+1)/2;
30             printf("%lld\n",len-mp[a]);
31         }
32     }
33     return 0;
34 }

 

 

QAQ

Problem Description

定义操作:将数 n 变为 f(n) = floor(sqrt(n))。即对一个数开平方后,再向下取整。
如对 2 进行一次操作,开平方再向下取整, 1.414213562..... = 1 , 即变为了 1 。
现在给出一个数 n,如果能在 5 次操作内把 n 变为 1,则输出操作次数;如果则超过5次输出"QAQ"。
数据范围:
1<= n <= 10^100

Input

多组输入,每行输入一个数 n。

Output

每组数据输出要多少次操作,或者输出"QAQ"

Sample Input

233
233333333333333333333333333333333333333333333333333333333

Sample Output

3
QAQ
如果长度大于10肯定要超过5次,其它的话就模拟下需要几次。
 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 int main(){
 5     string s;
 6     while(cin >> s){
 7         if(s.length() > 10){
 8             cout << "QAQ\n";
 9             continue;
10         }
11         ll ans = 0;
12         for(int i = 0; i < s.length(); i++){
13             ans = ans*10 + (ll)(s[i]-'0');
14         }
15         if(ans == 1) {
16             printf("0\n");
17             continue;
18         }
19         bool flag = false;
20         for(int i = 1; i <= 5; i ++){
21             ans = sqrt(ans);
22             if(ans == 1LL){
23                 flag = true;
24                 cout << i << endl;
25                 break;
26             }
27         }
28         if(!flag) printf("QAQ\n");
29     }
30     return 0;
31 }

 

posted @ 2017-11-18 17:07  starry_sky  阅读(419)  评论(0编辑  收藏  举报