题目链接: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
");
}
else {
printf("No
");
}
}
}
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
");
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
", 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("
");
}
}
L模拟+字典树
跟操作系统算法,金牌题
https://blog.csdn.net/Cymbals/article/details/102896091