2016 Multi-University Training Contest 6
来源:互联网 发布:百度深圳分公司 知乎 编辑:程序博客网 时间:2024/06/07 06:48
A
显然有规律可寻
#include <iostream>#include <cstdlib>#include <cstdio>#include <algorithm>#include <string>#include <map>#include <cstring>#include <stack>#include <queue>#include <cmath>#include <vector>#include <set>using namespace std;typedef long long LL;typedef pair<int, int> pii;const int MAXN = 1e5 + 10;const int INF = 1e9 + 10;const int MOD = 1e9 + 7;LL pow_mod(LL a, LL n) { LL ans = 1LL; while(n) { if(n & 1LL) { ans = ans * a % MOD; } a = a * a % MOD; n >>= 1LL; } return ans;}int main(){ int t; scanf("%d", &t); while(t--) { LL n, m; scanf("%lld%lld", &n, &m); printf("%lld\n", (pow_mod(m, n + 1) - 1 + MOD) % MOD * pow_mod(m - 1, MOD - 2) % MOD); } return 0;}
B
题意:每次从(x, y)可以到(x + 2, y + 1),(x + 1, y + 2)。中间有m个格子是坏的,问你从(1, 1) 到 (n, m)的方案数。
#include <iostream>#include <cstdlib>#include <cstdio>#include <algorithm>#include <string>#include <map>#include <cstring>#include <stack>#include <queue>#include <cmath>#include <vector>#include <set>#define ll o<<1#define rr o<<1|1using namespace std;typedef long long LL;typedef pair<LL, LL> pii;const int MAXN = 2e5 + 10;const int MOD = 110119;void add(LL &x, LL y) { x += y; if(x < 0) x += MOD; x %= MOD; }LL fac[MAXN];void getfac(LL p) { fac[0] = 1 % p; for(LL i = 1; i <= p; i++) { fac[i] = fac[i-1] * i % p; }}LL pow_mod(LL a, LL n, LL p) { LL ans = 1LL; while(n) { if(n & 1) ans = ans * a % p; a = a * a % p; n >>= 1; } return ans;}LL C(LL n, LL m, LL p) { if(m > n) return 0; else return fac[n] * pow_mod(fac[m] * fac[n-m] % p, p - 2, p) % p;}LL Lucas(LL n, LL m, LL p) { if(m == 0) { return 1 % p; } else { return C(n % p, m % p, p) * Lucas(n / p, m / p, p) % p; }}LL Solve(LL x1, LL y1, LL x2, LL y2) { if(x1 > x2 && y1 > y2) { swap(x1, x2); swap(y1, y2); } if(x1 <= x2 && y1 <= y2) { LL d = 2 * y2 - 2 * y1 + x1 - x2; if(d >= 0 && d % 3 == 0) { LL y = d / 3; d = x2 - y - x1; if(d < 0 || d & 1) return 0; LL x = d / 2; //cout << x << ' ' << y << endl; return Lucas(x + 1 + y - 1, x + 1 - 1, MOD); } } return 0;}pii a[110];LL dp[110];int main(){ getfac(MOD); LL n, m; int r, kcase = 1; while(scanf("%lld%lld%d", &n, &m, &r) != EOF) { for(int i = 1; i <= r; i++) { scanf("%lld%lld", &a[i].first, &a[i].second); dp[i] = 0; } sort(a + 1, a + r + 1); a[r + 1] = pii(n, m); r++; dp[r] = 0; for(int i = 1; i <= r; i++) { LL sum = 0; for(int j = 1; j < i; j++) { if(a[i].first >= a[j].first && a[i].second >= a[j].second) { add(sum, dp[j] * Solve(a[j].first, a[j].second, a[i].first, a[i].second) % MOD); } } add(dp[i], Solve(1, 1, a[i].first, a[i].second) - sum); } printf("Case #%d: %lld\n", kcase++, dp[r]); } return 0;}
C
题意:有n堆石子,每次可以选择从某一个非空堆里面取出不少于1数目的石子,也可以选择将该堆分为三堆石子(不允许为空)。
SG打表。
#include <iostream>#include <cstdlib>#include <cstdio>#include <algorithm>#include <string>#include <map>#include <cstring>#include <stack>#include <queue>#include <cmath>#include <vector>#include <set>using namespace std;typedef long long LL;typedef pair<int, int> pii;const int MAXN = 1e6 + 10;const int INF = 1e9 + 10;const int MOD = 1e9 + 7;int a[MAXN];int main(){ //freopen("out.txt", "w", stdin);// sg[0] = 0, sg[1] = 1, sg[2] = 2;// for(int i = 3; i <= 200; i++) {// sg[i] = Work(i);// }// for(int i = 3; i <= 200; i++) {// printf("%d %d %d\n", i, sg[i], sg[sg[i]]);// } int t; scanf("%d", &t); while(t--) { int n; scanf("%d", &n); LL ans = 0; for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); if(a[i] % 8 == 0) { a[i]--; } else if(a[i] % 8 == 7) { a[i]++; } ans ^= a[i]; } printf(ans ? "First player wins.\n" : "Second player wins.\n"); } return 0;}
H
日狗,看了好久不懂题意?
题意:
意思是让你找到若干个子集,使得
#include <iostream>#include <cstdlib>#include <cstdio>#include <algorithm>#include <string>#include <map>#include <cstring>#include <stack>#include <queue>#include <cmath>#include <vector>#include <set>#define ll o<<1#define rr o<<1|1using namespace std;typedef long long LL;typedef pair<int, int> pii;const int MAXN = 2e5 + 10;const int MOD = 1e9 + 7;void add(int &x, int y) { x += y; if(x >= MOD) x -= MOD; }int dp[1001][1001][3][3];int a[1001];int main(){ int t; scanf("%d", &t); while(t--) { int n, s; scanf("%d%d", &n, &s); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); } memset(dp, 0, sizeof(dp)); dp[0][0][0][0] = 1; for(int i = 1; i <= n; i++) { for(int j = 0; j <= s; j++) { for(int k = 0; k <= 2; k++) { for(int l = 0; l <= 2; l++) { if(j >= a[i]) { add(dp[i][j][k][l], dp[i - 1][j - a[i]][k][l]); if(k - 1 >= 0) { add(dp[i][j][k][l], dp[i - 1][j - a[i]][k - 1][l]); } } if(l - 1 >= 0) { add(dp[i][j][k][l], dp[i - 1][j][k][l - 1]); } add(dp[i][j][k][l], dp[i - 1][j][k][l]); } } } } int ans = 0; for(int i = 1; i <= s; i++) { add(ans, dp[n][i][2][2]); } printf("%lld\n", 1LL * 4 * ans % MOD); } return 0;}
J
题意:每次可以选择加一、不动、减一。选择减的话,如果上次减去x的话这次要减2*x,反之减1。问你最少需要多少次p可以到q。
思路:我们有两种决策——p一直升到大于q的最小值或者降到小于q的最大值,其实二者代价是相同的。我们就考虑降的策略时,中间记录一下需要停顿的次数rest,最后一次加的时候取差值和rest最大值即可。因为我们可以把停顿一次用做一次加操作。
#include <iostream>#include <cstdlib>#include <cstdio>#include <algorithm>#include <string>#include <map>#include <cstring>#include <stack>#include <queue>#include <cmath>#include <vector>#include <set>#define ll o<<1#define rr o<<1|1using namespace std;typedef long long LL;typedef pair<LL, LL> pii;const int MAXN = 2e5 + 10;const int MOD = 110119;void add(LL &x, LL y) { x += y; if(x < 0) x += MOD; x %= MOD; }LL fac[64];int Work(LL n) { int k = 0; while(fac[k] - 1 <= n) k++; return k;}LL Solve(LL p, LL q, LL ans, LL rest) { if(p <= q) { return ans + max(rest, q - max(0LL, p)); } LL l = p - q; int k = Work(l); if(fac[k - 1] - 1 == l) { return ans + k - 1 + rest; } return min(Solve(p - fac[k-1] + 1, q, ans + k - 1, rest + 1), Solve(p - fac[k] + 1, q, ans + k, rest));}int main(){ fac[0] = 1LL; for(int i = 1; i <= 62; i++) { fac[i] = fac[i - 1] * 2; } int t; scanf("%d", &t); while(t--) { LL q, p; scanf("%lld%lld", &p, &q); if(p < q) { printf("%lld\n", q - p); } else { printf("%lld\n", Solve(p, q, 0, 0)); } } return 0;}
0 0
- 2016 Multi-University Training Contest 6
- 2016 Multi-University Training Contest 6
- 2016 Multi-University Training Contest 6题解报告
- 2016 Multi-University Training Contest 6 解题报告
- hdu 5802 2016 Multi-University Training Contest 6(dfs)
- 2016 多校 Multi-University Training Contest 6 A Simple Chess
- 【2016 Multi-University Training Contest 6】【1002】【A Simple Chess】
- 2016 Multi-University Training Contest 1
- 2016 Multi-University Training Contest 1
- 2016 Multi-University Training Contest 2 Acperience
- 2016 Multi-University Training Contest 1
- 2016 Multi-University Training Contest 2
- 2016 Multi-University Training Contest 2 Acperience
- 2016 Multi-University Training Contest 2 Acperience
- 2016 Multi-University Training Contest 2 Eureka
- 2016 Multi-University Training Contest 2
- 2016 Multi-University Training Contest 3
- 2016 Multi-University Training Contest 3
- 获取相册照片和获取拍照照片原图(不被压缩)
- Android系统的启动流程
- C语言基础知识总结
- GSON
- QWebView隐藏时使用代码点击网页上的一个链接或按钮无效。
- 2016 Multi-University Training Contest 6
- 欢迎使用CSDN-markdown编辑器
- Android开源框架分析0——Volley框架详解
- 经常用border的solid,你知道border的这几种值吗?
- 欢迎使用CSDN-markdown编辑器
- 泛型指针,原生指针和智能指针
- Android快速开发系列 10个常用工具类
- Java线程详解
- 原创|Android逆向调试的打印调试信息定位代码位置的一个小技巧