华东交通大学2017年ACM“双基”程序设计竞赛
大吉大利今晚吃鸡
Problem Description
最近流行吃鸡,那就直接输出一行"Winner winner ,chicken dinner!"(没有双引号)
模板代码:
#include <stdio.h>
int main(){
printf("hello world\n");
return 0;
}
模板代码:
#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次操作后,他自己身在何方,能否到达自己喜欢的小姐姐身边。
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.代表管理员会把相邻的奇数和偶数位置上的男生互换。
接下来是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;
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
现在已知一个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 。
数据范围:
2 <= n <= 10^6 , 0 < 序列内的数 <= 10^6 。
Input
第一行输入一个 T,表示有 T 组数据。
接下来有 T 组数据,每组数据的第一行输入一个数 n ,第二行输入 n 个数。
接下来有 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
这n个随机数排成一个序列,MDD有q(q<=le5)个询问,
每个询问给你一个a,问你这个序列中有多少个区间的最大公约数不为a
Input
第一行输入一个T,表示T组测试样例
每组样例包含一个n,表示n个随机数
再输入一个Q,表示Q个询问
每个询问输入一个a
每组样例包含一个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
如对 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 }