2017 Multi-University Training Contest 2
来源:互联网 发布:淘宝订单自动关闭 编辑:程序博客网 时间:2024/06/05 10:07
1001 - Is Derek lying?
Problem
N 个问题,每个问题只有 A, B, C 三种选项。已知 Derek 和 Alfia 对每题的回答以及对应的最终得分(每题答对 1 分,错误 0 分)。问最终两人的得分是否一定错误。
Idea
根据两人的回答统计回答相同的题数 same 和不同的题数 diff 。记两人的得分分别为 x 和 y 。
- 得分和 - same > N ,一定说谎。
- x > diff 且 x-diff > y ,一定说谎。
- y > diff 且 y-diff > x ,一定说谎。
- 否则可能是真的。
Code
#include<bits/stdc++.h>using namespace std;const int N = 80000 + 10;int T, n, x, y;char a[N], d[N];int main(){ scanf("%d", &T); while(T-- && scanf("%d %d %d", &n, &x, &y)!=EOF) { scanf(" %s %s", a, d); int same = 0, diff; for(int i=0;i<n;i++) if(a[i] == d[i]) same++; diff = n - same; if(x > diff && x-diff > y) { printf("Lying\n"); } else if(y > diff && y-diff > x) { printf("Lying\n"); } else if(x+y - same > n) { printf("Lying\n"); } else { printf("Not lying\n"); } }}
1003 - Maximum Sequence
Problem
已知
构造限制为每次构造新的
Idea
由于每个
故贪心优先使用剩余的最小的
Code
#include<bits/stdc++.h>using namespace std;const int N = 250000 + 10;const int mod = 1e9 + 7;int n, a[N], b[N], mdfa[N];int main(){ while(scanf("%d", &n)!=EOF) { for(int i=1;i<=n;i++) scanf("%d", &a[i]); for(int i=1;i<=n;i++) scanf("%d", &b[i]); sort(b+1, b+n+1); mdfa[n+1] = 0; for(int i=n;i;--i) mdfa[i] = max(mdfa[i+1], a[i]-i); int amore = mdfa[b[1]]; long long ans = amore; amore -= n+1; for(int i=2;i<=n;i++) { if(mdfa[ b[i] ] > amore) { ans += mdfa[b[i]]; } else { ans += amore; } if(ans >= mod) ans %= mod; } printf("%lld\n", ans); }}
1004 - Puzzle
Problem
A Jigsaw puzzle contains
1.Sorting all the remaining jigsaws on the table in ascending order.
2.Picking out the 1st ,the P+1 th ,the 2*P+1 th,……the n*P+1 th jigsaws and put them back to the blank area in the board one by one from the top row to the bottom row,from the left column to the right column.
3.if there are jigsaws remained on the table,back to step 1.
After he arranging the board,it’s obvious that there’s only one blank area located at the bottom-right corner.
Your task is to make the numbers on jigsaws sorted with every row and every column in ascending order(From left to right,top to bottom),and the blank area should be located at the bottom-right corner in the end.Each step you can move the blank area’s neighboring jigsaws(which share a common side with the blank area) towards the blank area.It’s really a difficult question,so you need to write a program to judge whether it is possible to complete the task.
Idea
具体思路请参照 官方题解
说实话本来想更暴力的,结果出题人不良心,INPUT
表明
Code
#include<bits/stdc++.h>using namespace std;int T, n, m, p;int main(){ scanf("%d", &T); while(T-- && scanf("%d %d %d", &n, &m, &p)!=EOF) { if(p%2) { printf("YES\n"); continue; } int cntStep = 0, lft = n*m-1, item; while(lft>0) { item = (lft+p-1) / p; lft -= item; if(item%4==0 || item%4==1) continue; cntStep++; } printf("%s\n", cntStep%2?"NO":"YES"); }}
1006 - Funny Function
Problem
给定 N 和 M,求
Limit
Idea
官方题解请见:LINK
个人偷懒直接找规律用特征数列 AC 。
对应每个 m ,
当 n = 2 时数列:1, 2, 6, 18, 54…
当 n = 3 时数列:1, 5, 33, 229, 1601…
当 n = 4 时数列:1, 10, 150, 2250…
当 n = 5 时数列:1, 21, 641, 19861…
…
存在一个特征数列 1, 5, 33, 229, 1601, 11205, 78433, 549029, 3843201, 26902405, 188316833, 1318217829, 9227524801, 64592673605,
452148715233, 3165041006629, 22155287046401, 155087009324805, 1085609065273633, 7599263456915429, 53194844198408001
的通项公式为
故 n 为奇数时,
n 为偶数时,
HINT:对于特征数列的积累,可以经常逛逛 oeis 。
Code
#include<bits/stdc++.h>using namespace std;const int mod = 1e9 + 7;const int maxn = 5, maxm = 5;int T;long long n, m;long long pow_mod(long long a, long long i) { long long ans = 1; while(i >= 1) { if(i&1) (ans *= a) %= mod; i >>= 1; (a *= a) %= mod; } return ans;}int main(){ scanf("%d", &T); while(T--) { scanf("%lld %lld", &n, &m); if(m == 1 || n == 1) { printf("1\n"); continue; } long long mul = (pow_mod(2, n)-1+mod) % mod; long long fin = 2 * pow_mod(mul, m-1) % mod; if(n%2) fin++; (fin *= 333333336) %= mod; printf("%lld\n", fin); }}
1008 - To my boyfriend
Problem
对于给定的
Idea
统计每种数字对多少子矩阵作贡献。每个子矩阵中多个相同数字贡献只记一次。
由于 (x, y)
。统计以 (x, y)
为任意矩阵中所有该数字最左上点的矩阵个数。
具体统计方案为:
- 已知任意矩阵下边界
>=x 均满足条件,故下边界的方案有(n-x+1)
种。 - 对于上边界,从
up=x
到up=1
逐一枚举,在过程中维护其左右边界的取值方案。 - 每种上边界的枚举有
(x, y)
所代表的数字对(n-x+1) * (y-Left+1) * (Right-y+1)
个矩阵都存在贡献。
Code
#include<bits/stdc++.h>using namespace std;const int N = 100+10, M = 100+10;int T, n, m, g[N][M];long long calc(int x, int y) { int num = g[x][y], lft = 1, rgt = m; long long ret = 0; for(int up=x;up;up--) { if(up!=x && g[up][y] == num) break; for(int l=y-1;l>=lft;l--) if(g[up][l] == num) { lft = l+1; break; } if(up!=x) { for(int r=y+1;r<=rgt;r++) if(g[up][r] == num) { rgt = r-1; break; } } ret += (n-x+1ll) * (y-lft+1ll) * (rgt-y+1ll); } return ret;}int main(){ scanf("%d", &T); while(T-- && scanf("%d %d", &n, &m)!=EOF) { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d", &g[i][j]); long long ans = 0, tot = 0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) ans += calc(i, j), tot += i*j; printf("%.9lf\n", ans*1.0/tot); }}
1009 - TrickGCD
Problem
对于给定的 A 数组,求有多少种不同的构造方案,使得 B 数组满足:
1≤Bi≤Ai - 对于任意区间
[l, r]
,gcd(bl,bl+1,⋯,br)≥2
Limit
Idea
对任意区间 gcd 结果 [1, n]
种所有
枚举每一个合法的 gcd 值 2~min(A[i])
。利用容斥,其中含奇数个质因子的对结果的贡献为正,含偶数个质因子的对结果贡献为负,忽略形如
对每个枚举的 gcd ,可以知道
Code
#include<bits/stdc++.h>using namespace std;const int N = 100000 + 10;const long long mod = 1e9 + 7;int T, n, a[N], ca[N], mn, mx, cnt[N];bool isSqr[N];void prime() { memset(isSqr, false, sizeof(isSqr)); for(int i=2;i<=100000;i++) { if(cnt[i]) continue; for(int j=i;j<=100000;j+=i) { cnt[j]++; if(j % ((long long)i*i) == 0) isSqr[j] = 1; } }}long long pow_mod(long long a,long long i) { long long ans = 1; while(i >= 1) { if(i&1) (ans *= a) %= mod; i >>= 1; (a *= a) %= mod; } return ans;}int calFac(int gcd) { long long ret = 1; for(int i=2;i<=100000;++i) { if(gcd * i > mx) return ret; int num = ca[min(100000, gcd*(i+1)-1)] - ca[gcd*i-1]; if(num==0) continue; ret *= pow_mod(i, num); if(ret >= mod) ret %= mod; }} int main(){ prime(); scanf("%d", &T); for(int ica=1;ica<=T && scanf("%d", &n)!=EOF;ica++) { memset(ca, 0, sizeof(ca)); mx = 0, mn = 100000; for(int i=1;i<=n;i++) { scanf("%d", &a[i]); ca[ a[i] ]++; mn = min(a[i], mn); mx = max(a[i], mx); } if(mn == 1) { printf("Case #%d: 0\n", ica); continue; } for(int i=1;i<=100000;i++) ca[i] += ca[i-1]; int ans = 0, fac; for(int i=2;i<=mn;i++) { if(isSqr[i] == 1) continue; fac = calFac(i); if(cnt[i]%2) ans += fac; else ans -= fac; ans %= mod; } (ans += mod) %= mod; printf("Case #%d: %d\n", ica, ans); }}
1011 - Regular polygon
Problem
二维坐标系上的 N (
Idea
由于每种正多边形的顶角度数已知,可以简单考虑得出在已知一边的情况下构造的正多边形(除正方形外)均有点将落在非整数点上。
故只需统计正方形个数。枚举任意两个点,构造剩余两个点并
Code
#include<bits/stdc++.h>using namespace std;int n, x[550], y[550];map<pair<int, int>, int> mp;pair<int, int> p, q;int main(){ while(scanf("%d", &n)!=EOF) { mp.clear(); for(int i=1;i<=n;i++) { scanf("%d %d", &x[i], &y[i]); mp[make_pair(x[i], y[i])] = i; } long long ans = 0; for(int i=1, dx, dy;i<=n;i++) for(int j=i+1;j<=n;j++) { if(i == j) continue; p = make_pair(x[i]+(y[j]-y[i]), y[i]+(x[i]-x[j])); q = make_pair(x[j]+(y[j]-y[i]), y[j]+(x[i]-x[j])); if(mp.find(p) != mp.end() && mp.find(q) != mp.end()) ans++; p = make_pair(x[i]-(y[j]-y[i]), y[i]-(x[i]-x[j])); q = make_pair(x[j]-(y[j]-y[i]), y[j]-(x[i]-x[j])); if(mp.find(p) != mp.end() && mp.find(q) != mp.end()) ans++; } printf("%lld\n", ans / 4); }}
- 2017 Multi-University Training Contest 2 1011
- #2017 Multi-University Training Contest 2 1001
- #2017 Multi-University Training Contest 2 1003
- 2017 Multi-University Training Contest 2
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- #2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- BZOJ 3670 浅谈KMP算法的拓展应用
- SnailApp---数据流的控制(一)
- POJ 1486 Sorting Slides 二分图关键边 匈牙利算法
- 【java】吸血鬼数字
- [第五季]10.CSS文本样式
- 2017 Multi-University Training Contest 2
- [bzoj4516][Sdoi2016]生成魔咒 SAM
- uva 11481 一个序列前m个中有k个不动,其他可动可不动 共有几种情况
- C# 与java的比较
- Piggy-Bank
- 面试---算法排序(2)(插入排序)
- Find The Multiple
- python学习中的一些问题
- SnailApp---数据流的控制(二)