2021江西省赛 2021 Jiangxi Provincial Collegiate Programming Contest
2021 Jiangxi Provincial Collegiate Programming Comuqintest
目前做了: ABHKL
https://codeforces.com/gym/103366
A. Mio visits ACGN Exhibition
数字三角形模型,只依赖于前一个状态,并且总数量很大,所以可以使用滚动数组优化转移过来。(滚动数组)
因为只能往右和下走,所以路径长度是固定的\(n+m-1\)
#include <bits/stdc++.h>
using namespace std;
const int N = 505, M = 1010, mod = 998244353;
int f[2][N][M]; //滚动数组优化 //0的个数
int a[N][N];
int n, m, p, q;
int main () {
cin >> n >> m >> p >> q;
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= m; j ++)
cin >> a[i][j];
if (a[1][1] == 0)
f[1][1][1] = 1;
else
f[1][1][0] = 1;
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= m; j ++) {
if (i == 1 && j == 1)
continue; //初状态已经更新好,不需要转移
if (a[i][j] == 0) {
f[i % 2][j][0] = 0;
for (int k = 1; k < M; k ++)
f[i % 2][j][k] = (f[i % 2][j - 1][k - 1] + f[(i - 1) % 2][j][k - 1]) % mod;
}
else {
for (int k = 0; k < M; k ++)
f[i % 2][j][k] = (f[i % 2][j - 1][k] + f[(i - 1) % 2][j][k]) % mod;
}
}
int ans = 0;
for (int i = p; i <= n + m - 1 - q; i ++)
ans = (ans + f[n % 2][m][i]) % mod;
cout << ans << endl;
}
//从(1,1)到(n,m)至少经过p个0,q个1
//有多少种可能
//dp 倒推
//数字三角形模型
//维度
//路径长度是固定的 n+m-1,所以记录1的数量j,那么1的数量就是n+m-1-j
//滚动数组优化!!
B. Continued Fraction
经过模拟其运算规则可以发现,这是一个类似辗转相除的东西,xy迭代更新(y变模数,x变上一个y)(最终余数为1的时候就表示除完了)
另:当x<y时要交换,要不然会出现除0的异常
#include <bits/stdc++.h>
using namespace std;
const int N = 105;
int x, y;
vector <int> v;
void solve () {
cin >> x >> y;
if (x < y)
v.push_back (0), swap (x, y);
while (y != 1) {
//y变成模数, x变成上一个y
int a = x / y;
if (a == 0)
swap (x, y);
int mod = x % y;
v.push_back (a);
x = y, y = mod;
}
if (x)
v.push_back (x);
cout << v.size () - 1 << ' ';
for (auto i : v)
cout << i << ' ';
cout << endl;
v.clear ();
}
int main () {
int t;
cin >> t;
while (t --) {
solve ();
}
}
//有点类似辗转相除
// x/y作为ai, x%y作为下一个y, x/y==0 || y == 0时结束
//注意y可能变为0,那么在整除的时候就会出现浮点数异常
//真分数eg. 3/13
//倒过来先
//分母为1就结束
H. Hearthstone So Easy
这是一道需要大胆猜结论的题目(我大胆猜测,然后一发入魂,贼激动)。
当先手没办法一击毙命B的时候,他就输了(因为先手取牌一定会有消耗,而后手抽完牌之后就有办法整死先手了hhh)
大概就这个意思吧,我也不太会证明
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve () {
int n, k;
cin >> n >> k;
if (n == 1) {
cout << "freesin" << endl;
return ;
}
if (k + 1 >= n)
cout << "pllj" << endl;
else
cout << "freesin" << endl;
}
signed main () {
int t;
cin >> t;
while (t --) {
solve ();
}
}
//初始都有n的血量,抽牌消耗1滴血
//抽完牌后可以选择给自己增加k 或 给别人减少k
//大胆猜测,如果a没办法一击毙命,那他自己就会死
K. Many Littles Make a Mickle
简单模拟,预处理平方和,然后再乘m即可
#include <bits/stdc++.h>
#define int long long
using namespace std;
int a[105];
signed main () {
a[1] = 1;
for (int i = 2; i <= 100; i ++)
a[i] = i * i + a[i - 1];
int t;
cin >> t;
while (t --) {
int n, m;
cin >> n >> m;
cout << a[n] * m << endl;
}
}
L. It Rains Again
就是被覆盖到的区间标记一下,然后统计最终的长度
(一开始写的区间合并,不知道为啥WA,害)
这做法害挺巧妙的,可以积累一下
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
const int N = 100005;
int maxn = 0, ans;
bool vis[N];
int main () {
IOS;
int n;
cin >> n;
while (n --) {
int x, y, xx, yy;
cin >> x >> y >> xx >> yy;
maxn = max (maxn, xx);
for (int i = x; i < xx; i ++) {
if (vis[i])
break;
vis[i] = true;
}
//反着也扫一遍
for (int i = xx - 1; i >= x; i --) {
if (vis[i])
break;
vis[i] = true;
}
}
for (int i = 1; i < maxn; i ++)
if (vis[i])
ans ++;
cout << ans << "\n";
}
//整复杂了,直接扫一遍标记就得了
//n个挡雨的,求不会被雨淋到的长度
//直接看不相交区间
//只考虑横坐标
//区间合并
//差分