第四届“图灵杯”NEUQ-ACM程序设计竞赛(团队赛)【solved 7 / 10】
来源:互联网 发布:异形1知乎 编辑:程序博客网 时间:2024/05/22 22:27
http://oj.acmclub.cn/contest.php
问题 A: 谷神的赌博游戏(计数问题)
思路:
都看成同余3的情况,那么有n+1个1,n个0 ,n个2。那么计算前缀和sum的时候,我们会发现只有三种情况:0,1,2.当前缀和为0的时候,我们可以添加1或者2,当前缀和为1的时候,我们可以添加1或者0,当前缀和为2的时候我们可以添加2或者0。
又因为我们发现0插在哪里,都不会影响串的合法性,那么我们可以先不考虑0。先只考虑1和2,我们会发现,如果让1打头以后,一定是112 然后12交替,类似112121212的串。只有一种情况。如果让2打头一定是221212121,但是考虑到1比2多一个,所以最后一定是会不合法的,自己画一下就知道了。那么我们得到不包含0的时候我们只有一个合法串,那就是112121212,这种串吧 串长为n+1+n n个2排列是 n!,n+1个1的排列是(n+1)!,那么 1121212121 这个串在变成123456789这种数字的时候 应该n!*(n+1)!种吧。
然后0不能插在第一个1的右边,其他都能插,就变成 n个0插到2n+1个位置,每个位置0的个数大于等于0。这是一个计数基础问题,看过大白书第二章的应该都会,答案就是x1+x2+....+x(2n+1)=n. xi >= 0,那就是组合数C(3n, n)。再考虑到0也有n个,有n!种排列。(3n+1)!/ ( n! * (n + 1)! * C(3n, n) *n! )
#include<bits/stdc++.h>using namespace std;typedef long long LL;int main(){ int T; scanf("%d", &T); while(T--) { LL a[20]; int cas; scanf("%d", &cas); for(int i = 0; i < 10; i++) scanf("%lld", &a[i]); sort(a, a + 10); set<LL>s; LL ans = a[9]; for(int i = 9; i >= 0; i--) { s.insert(a[i]); if(s.size() == 3) ans = a[i]; } printf("%d %lld\n", cas, ans); } return 0;}
问题 B: 一个简单的问题(water)
#include<bits/stdc++.h>using namespace std;typedef long long LL;int main(){ int T; scanf("%d", &T); while(T--) { LL a[20]; int cas; scanf("%d", &cas); for(int i = 0; i < 10; i++) scanf("%lld", &a[i]); sort(a, a + 10); set<LL>s; LL ans = a[9]; for(int i = 9; i >= 0; i--) { s.insert(a[i]); if(s.size() == 3) ans = a[i]; } printf("%d %lld\n", cas, ans); } return 0;}
问题 C: 来简单地数个数(大数)
思路:
懒得写大数....反正平时怎么做的,这题就怎么做,打个表,二分一下。只不过需要在大数下做。
问题 D: 简单的图形输出(递归?分形。)
#include<bits/stdc++.h>using namespace std;char s[1030][2050]; void show(int x, int y, int n){ if(n == 1) { s[x][y] = '/', s[x][y + 1] = '\\';//, s[x][y +2] = '\n'; s[x + 1][y - 1] = '/', s[x + 1][y] = s[x + 1][y + 1] = '_', s[x + 1][y + 2] = '\\';//, s[x + 1][y + 3] = '\n'; return ; } int blank = (1 << (n - 1)); show(x, y, n - 1); show(x + blank, y - blank, n - 1); show(x + blank, y + blank, n - 1);} int main(){ int n; while(~scanf("%d", &n)) { if(n == 0) break; for(int i = 1; i <= (1 << n); i++) { for(int j = 1; j <= (1 << (n + 1)); j++) { s[i][j] = ' '; } } show(1, (1 << n), n); int k =(1 << n) + 1; for(int i = 1; i <= (1 << n); i++, k++) { for(int j = 1; j <= k; j++) { putchar(s[i][j]); }puts(""); } puts(""); } return 0;}
问题 E: 简单的 RMQ(ST表)
题意:
大白书原题。要求的是区间最大的查询,不涉及修改,那么可以联想到st表,因为是一个单调序列,所以相同数字一定是放在一起的。那么是不是显然,求出每段不同数字的长度,然后用st表来搞一下。再记录一下每段的左右边界,把输入的left和right,转换成对应的数字段号,就能查询了。
#include<bits/stdc++.h>using namespace std;typedef long long LL;const int maxn = 1e5 + 5;int d[maxn][18];int a[maxn], l[maxn], r[maxn], num[maxn], belong[maxn];void initRMQ(int n, int a[]){ for(int i = 0; i < n; i++) d[i][0] = a[i]; for(int j = 1; (1 << j) <= n; j++) { for(int i = 0; i + (1 << j) - 1 < n; i++) { d[i][j] = max(d[i][j - 1], d[i + (1 << (j - 1))][j - 1]); } }} int query(int l, int r){ int k = 0; while((1 << (k + 1)) <= r - l + 1) k++; return max(d[l][k], d[r - (1 << k) + 1][k]);} int main(){ int n, q; while(~scanf("%d", &n)) { if(n == 0) break; memset(l, -1, sizeof(l)); memset(r, -1, sizeof(r)); memset(num, 0, sizeof(num)); memset(belong, -1, sizeof(belong)); scanf("%d", &q); int cnt = -1; for(int i = 0; i < n; i++) { int x; scanf("%d", &x); a[i] = x; if(i == 0 || a[i] != a[i - 1]) { cnt++; l[cnt] = r[cnt] = i; } else { r[cnt] = i; } belong[i] = cnt; } cnt++; for(int i = 0; i < cnt; i++) { num[i] = r[i] - l[i] + 1; } initRMQ(cnt, num); while(q--) { int ql, qr; scanf("%d%d", &ql, &qr); ql--, qr--; int a = belong[ql], b = belong[qr]; if(a == b) { printf("%d\n", qr - ql + 1); } else if(b - a == 1) { printf("%d\n", max(r[a] - ql + 1, qr - l[b] + 1)); } else { int ans = query(a+1, b-1); ans = max(ans, max(r[a] - ql + 1, qr - l[b] + 1)); printf("%d\n", ans); } } } return 0;}
问题 F: 一道简单的递推题(矩阵快速幂)
题意:
勘误!题目的递推式应该是F(m + 1) = A1 * F(m) + ... + An * F(m-n+1)。
那么就是一个矩阵快速幂的裸题了。注意一个幂是LL,憋爆int了。还有一个矩阵快速幂的时候,0优化,for i,j,k,这种会T。for k,i,j的0优化能快很多。
#include <bits/stdc++.h>using namespace std;typedef long long LL; const LL mod = 1000000007;const int mSize = 100; struct Matrix{ long long v[mSize][mSize]; friend Matrix operator* (const Matrix& a, const Matrix& b) { Matrix c; memset(c.v, 0, sizeof(c.v)); for (int k = 0; k < mSize; k++) { for (int i = 0; i < mSize; i++) { if(a.v[i][k] == 0) continue; for (int j = 0; j < mSize; j++) { if(b.v[k][j] == 0) continue; c.v[i][j] += a.v[i][k] * b.v[k][j] % (mod); c.v[i][j] %= (mod); } } } return c; } friend Matrix operator^ (Matrix x, LL n) { Matrix ans; for (int i = 0; i < mSize; i++) for (int j = 0; j < mSize; j++) ans.v[i][j] = (i == j); while (n) { if (n & 1) ans = ans * x; x = x * x; n >>= 1; } return ans; }}; long long f[105], a[105];int main(){ LL n, k; while(~scanf("%lld%lld", &n, &k)) { for(int i = 0; i < n; i++) scanf("%lld", &f[i]); for(int i = 0; i < n; i++) scanf("%lld", &a[i]); if(k == 1) { printf("%lld\n", f[0]); return 0; } else if(k == 2) { printf("%lld\n", f[1]); return 0; } else { Matrix mat; memset(mat.v, 0, sizeof(mat.v)); for(int i = 0; i < n; i++) mat.v[0][i] = a[i]; for(int i = 1; i < n; i++) mat.v[i][i - 1] = 1; LL mi = k - n; mat = mat ^ mi; LL ans = 0; for(int i = 0; i < n; i++) ans += mat.v[0][i] * f[n - 1 - i] % mod, ans %= mod; printf("%lld\n", ans); } } return 0;}
问题 G: 那么大奶牛之神(据说是个= = 试错题)
问题 H: 简单的机械臂设计(splay伸展树。)
问题 I: 一道不简单的题目 (water)
问题 J: 简单的变位词(water)
题意:
如果组数相同,则比较两个组中,各自字典序最小的单词,按字典序。
#include<bits/stdc++.h>using namespace std;typedef long long LL;const int maxn = 1e5 + 5; vector<string>vec[30000 + 4];map<string, int>ma; bool cmp(const vector<string>&a, const vector<string>&b){ if(a.size() != b.size()) return a.size() > b.size(); return a[0] < b[0];}int main(){ string s; int cnt = 1; int k = 0; while(cin >> s) { int len = s.size(); string str = ""; string store = s; sort(s.begin(), s.end()); for(int i =0; i < len; i++) str += s[i]; if(ma[str] == 0) ma[str] = cnt++; int id = ma[str]; vec[id].push_back(store); } for(int i = 1; i <= cnt; i++) sort(vec[i].begin(), vec[i].end()); sort(vec + 1, vec + 1 + cnt, cmp); for(int i = 1; i <= cnt && i <= 5; i++) { printf("Group of size %d:", vec[i].size()); set<string>temp; for(auto o : vec[i]) temp.insert(o); for(auto o : temp) cout << " " << o; printf(" .\n"); } return 0;}
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛(团队赛)【solved 7 / 10】
- 第四届“图灵杯”NEUQ-ACM 程序设计竞赛(团队赛)
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛(团队赛)-网络同步赛A(组合数学)
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛(团队赛)-网络同步赛B(排序)
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛(团队赛)-网络同步赛E(线段树)
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛(团队赛)-网络同步赛D 分形
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛(团队赛)—A
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛总结 【8/10】
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛(团队赛)-网络同步赛C(大数斐波那契数)
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛(团队赛)-网络同步赛F(矩阵快速幂)
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛(团队赛)-网络同步赛J(字典树 or map)
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛部分题解
- **第四届“图灵杯”NEUQ-ACM程序设计竞赛(个人赛)C粉丝与汉诺塔
- 图灵杯-第四届“图灵杯”NEUQ-ACM 程序设计竞赛-C-来简单地数个数
- 图灵杯-第四届“图灵杯”NEUQ-ACM 程序设计竞赛-D-简单图形输出
- 图灵杯-第四届“图灵杯”NEUQ-ACM 程序设计竞赛-J-简单的变位词
- 图灵杯-第四届“图灵杯”NEUQ-ACM 程序设计竞赛-E-简单的RMQ
- 图灵杯-第四届“图灵杯”NEUQ-ACM 程序设计竞赛-A-谷神的赌博游戏
- 霍夫曼编码应用
- 深度解密 python challenge第4关之 小小的爬虫
- TensorFlow教程05:MNIST深度学习初探
- OpenCV 2.4.9 支持向量机(SVM)说明
- 强力Django 和杀手级xadmin
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛(团队赛)【solved 7 / 10】
- JDBC的运用
- 安装vmware以后apache无法启动解决办法
- Latex中添加sty文件
- 第三讲_从数据库中拿数据到Java程序中并在新窗口中显示
- Centos7升级gcc学习笔记
- 软件工程第七章知识点总结
- POJ 2058 Word Encoding 笔记
- kali 下metasploit (msf)初始化使用