2019ccpc哈尔滨(补题)
题目链接:https://vjudge.net/contest/398996
榜单:https://ccpc.io/index.php/a/185.html
获奖名单:https://ccpc.io/index.php/a/191.html
A题
差分约束,最短路,会了再写,金牌题
https://www.cnblogs.com/mollnn/p/11806134.html
B题
动态规划,二进制,状态设计,会了再写,金牌题
https://blog.csdn.net/m0_37809890/article/details/102886956
C题
大模拟
D题
没人过
E题
拓扑排序
https://www.cnblogs.com/--HPY-7m/p/11785514.html
F题
DFS
题意:六个字符串中,每个字符串选一个字母,问能不能构成harbin
思路:用二维数组构建图graph,graph[1][2]代表第2个字符串中有h这个字母,用这个思想,构建出图来
然后DFS直接搜索有无答案。
#include<bits/stdc++.h> using namespace std; bool ok = 0; bool a[10][10]; bool v[10]; void DFS(int x) { if(ok) return; if(x > 6) { ok = 1; return; } for(int i = 1; i <= 6; ++i) { if(!v[i] && a[i][x]) { v[i] = 1; DFS(x + 1); v[i] = 0; } } } int main () { int T; scanf("%d", &T); while(T--) { memset(a, 0, sizeof a); int num = 6; for(int j = 1; j <= 6; ++j){ string s; cin >> s; for(int i = 0; i < s.size(); ++i) { if(s[i] == 'h') { a[1][j] = 1; } else if(s[i] == 'a') { a[2][j] = 1; } else if(s[i]== 'r') { a[3][j] = 1; } else if(s[i] == 'b') { a[4][j] = 1; } else if(s[i] == 'i') { a[5][j] = 1; } else if(s[i] == 'n') { a[6][j] = 1; } } } ok = 0; memset(v, 0,sizeof v); DFS(1); // //打表 // for(int i = 1; i <= 6; ++i) { // for(int j = 1; j <= 6; ++j) { // cout << a[i][j] << " "; // } // cout << endl; // } if(ok) { printf("Yes\n"); } else { printf("No\n"); } } }
G题
https://blog.csdn.net/qq_33229466/article/details/103031399
【Nim-K+线性基+bitset优化三进制加法】,会了再写
H题
https://blog.csdn.net/qq_33229466/article/details/103003822
【点分树+最短路】
I题
组合数问题
思路:1.h数组任何值必须小于n并且后一个元素比前一个元素大并且第一个元素为0,否则结果为0
定义gap为中间所有可以取的情况数
2.两种情况:如果后一个元素比前一个大,答案为加上这个元素前的组合的两倍。为什么?因为加上第n个元素后,1到n-1与2到n本质上来讲是一种情况,区别就是最后一个元素放的是最大还是最小。因为后一个比前一个大了,所以新加上的元素一定要么是最小要么是最大,如果是中间大小,不会影响后一个元素与前一个元素相等。此时gap+=后一个元素 - 前一个元素 - 1。中间可以取的元素数组可能会增加
如果后一个元素和前一个相等,那么可以取的值是中间的情况。使用完后 gap--;
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll MODE = 1e9 + 7; ll a[100000 + 10]; int main () { int T; ios::sync_with_stdio(false); cin.tie(0); cin >> T; // scanf("%d", &T); while(T--) { int n; cin >> n; // scanf("%d", &n); memset(a, 0, sizeof a); for(int i = 0; i < n; ++i) { cin >> a[i]; // scanf("%d", &a[i]); } ll ans = 1; bool ok = 0; for(int i = 1; i < n; ++i) { if(a[i] - a[i - 1] < 0 || a[i] >= n) { ok = 1; break; } } if(a[0] != 0 || ok) { // printf("0\n"); cout << 0 << endl; continue; } ll gap = 0; for(int i = 1; i < n; ++i) { if(a[i] > a[i - 1]) { ans = (ans * 2) % MODE; gap = (gap + a[i] - a[i - 1] - 1) % MODE; } else { ans = (ans * gap) % MODE; gap--; } } cout << ans % MODE << endl; // printf("%lld\n", ans % MODE); } }
J题
签到题
#include<bits/stdc++.h> using namespace std; int main () { ios::sync_with_stdio(false); cin.tie(0); int T; cin >> T; while(T--) { int n; cin >> n; if(n <= 5) { cout << -1 << endl; continue; } if(!(n & 1)) { cout << 2 << " " << n - 2 << endl; } else { cout << 3 << " " << n - 3 << endl; } } }
K题
签到题
#include<bits/stdc++.h> using namespace std; int main () { int T; scanf("%d", &T); while(T--) { int n; double k; scanf("%d%lf", &n, &k); vector<double> a(n); double sum = 0; for(int i = 0; i < n; ++i) { scanf("%lf", &a[i]); sum += a[i]; } for(int i = 0; i < n; ++i) { printf("%.8lf", (1.0 + k / sum) * a[i]); if(i != n- 1) { printf(" "); } } printf("\n"); } }
L模拟+字典树
跟操作系统算法,金牌题
https://blog.csdn.net/Cymbals/article/details/102896091