矩形
当
时,使用双指针遍历上下边界,同时扫描中间的节点,如果可以更新该段的最小矩阵大小,则进行更新,等全部扫描完后再进行覆盖,同时上边界向下遍历,下边界向上遍历,可以保证数据不会重复使用,反之遍历左右界,从上到下扫描更新,复杂度为
。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 1E9;
void solve() {
int n, m;
cin >> n >> m;
vector<string> s(n);
for (int i = 0; i < n; i ++ ) cin >> s[i];
vector<vector<int>> ans(n, vector<int>(m, INF));
if (n < m) {
for (int i = 0; i < n; i ++ ) {
vector<int> mi(m, INF);
for (int j = n - 1; j > i; j -- ) {
int last = -1;
for (int k = 0; k < m; k ++ ) {
if (s[i][k] == '1' && s[j][k] == '1') {
if (last != -1) {
int cnt = (j - i + 1) * (k - last + 1);
for (int u = last; u <= k; u ++ ) {
mi[u] = min(mi[u], cnt);
}
}
last = k;
}
}
for (int k = 0; k < m; k ++ ) {
ans[j][k] = min(ans[j][k], mi[k]);
}
}
for (int k = 0; k < m; k ++ ) {
ans[i][k] = min(ans[i][k], mi[k]);
}
}
} else {
for (int i = 0; i < m; i ++ ) {
vector<int> mi(n, INF);
for (int j = m - 1; j > i; j -- ) {
int last = -1;
for (int k = 0; k < n; k ++ ) {
if (s[k][i] == '1' && s[k][j] == '1') {
if (last != -1) {
int cnt = (j - i + 1) * (k - last + 1);
for (int u = last; u <= k; u ++ ) {
mi[u] = min(mi[u], cnt);
}
}
last = k;
}
}
for (int k = 0; k < n; k ++ ) {
ans[k][j] = min(ans[k][j], mi[k]);
}
}
for (int k = 0; k < n; k ++ ) {
ans[k][i] = min(ans[k][i], mi[k]);
}
}
}
for (int i = 0; i < n; i ++ ) {
for (int j = 0; j < m; j ++ ) {
if (ans[i][j] == INF) ans[i][j] = 0;
cout << ans[i][j] << ' ';
}
cout << endl;
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int tt = 1;
cin >> tt;
while (tt--) {
solve();
}
return 0;
}
怎么还是猫娘
统计所有 'nya' 子串的位置,统计一下有那些子串可以包含这些小的 'nya',用左端点到上一段的末端,乘上右端点到结尾的长度,就是总的结果。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;
void solve() {
int n;
string s;
cin >> n >> s;
vector<int> ne;
for (int i = 0; i < n - 2; i ++ ) {
if (s[i] == 'n' && s[i + 1] == 'y' && s[i + 2] == 'a') ne.push_back(i);
}
LL last = -1;
LL ans = 0;
for (int i = 0; i < ne.size(); i ++ ) {
ans = (ans + (ne[i] - last) * (n - ne[i] - 2) % MOD) % MOD;
last = ne[i];
}
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int tt = 1;
cin >> tt;
while (tt--) {
solve();
}
return 0;
}
逃离迷宫
多源BFS遍历所有出口可以到达的坐标,统计有多少人会被遍历到,复杂度为 O(n·m);
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int main() {
int n, m;
cin >> n >> m;
vector<string> s(n);
vector<vector<bool>> st(n, vector<bool>(m, 0));
for (int i = 0; i < n; i ++ ) {
cin >> s[i];
}
int ans = 0;
queue<PII> q;
for (int i = 0; i < n; i ++ ) {
for (int j = 0; j < m; j ++ ) {
if (s[i][j] == 'y') {
q.push({i, j});
st[i][j] = true;
}
}
}
while (q.size()) {
auto t = q.front();
q.pop();
for (int i = 0; i < 4; i ++ ) {
int a = t.first + dx[i], b = t.second + dy[i];
if (a < 0 || a >= n || b < 0 || b >= m) continue;
if (st[a][b]) continue;
if (s[a][b] == '#') continue;
st[a][b] = true;
if (s[a][b] == 'x') ans ++ ;
q.push({a, b});
}
}
cout << ans << endl;
return 0;
}
逮捕猫娘
用前缀和统计一下,同时注意边界处理。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
int main() {
int n, m;
cin >> n >> m;
string s;
cin >> s;
s = " " + s;
vector<int> sum(n + 1, 0);
for (int i = 3; i <= n; i ++ ) {
if (s[i - 2] == 'n' && s[i - 1] == 'y' && s[i] == 'a') sum[i] ++ ;
sum[i] = sum[i] + sum[i - 1];
}
while (m -- ) {
int l, r;
cin >> l >> r;
cout << sum[r] - sum[l + 1] << endl;
}
return 0;
}
猫娘计数
很经典的状态机dp,对于状态1,只有遇到
才会增加,遇到
状态 2 会加上状态 1 的个数,表示当前能组成
的子序列个数,状态 3 同理。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;
void solve() {
int n;
cin >> n;
string s;
cin >> s;
vector<LL> f(3, 0);
for (int i = 0; i < n; i ++ ) {
if (s[i] == 'n') f[0] = (f[0] + 1) % MOD;
if (s[i] == 'y') f[1] = (f[1] + f[0]) % MOD;
if (s[i] == 'a') f[2] = (f[2] + f[1]) % MOD;
}
cout << f[2] << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int tt = 1;
cin >> tt;
while (tt--) {
solve();
}
return 0;
}
不再美丽
只有使两个不能被同化的元素贴在一起,才能使元素变得丑陋,也就是求和第一个元素相同的连续子串的最短长度,或者删除所有开头/结尾的相同字符,使头尾不相等。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
void solve() {
int n;
cin >> n;
vector<int> a(n, 0);
int ans = n;
for (int i = 0; i < n; i ++ ) {
cin >> a[i];
}
if (a[0] != a[n - 1]) {
cout << 0 << endl;
return;
}
for (int i = 0, last = 0; i < n; i ++ ) {
if (a[0] == a[i]) last ++ ;
if (i == n - 1 || a[0] != a[i]) {
ans = min(ans, last);
last = 0;
}
}
if (ans == n) ans = -1;
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int tt = 1;
cin >> tt;
while (tt--) {
solve();
}
return 0;
}
年轮
分别统计月份前的天数,再加上该月已经经过的天数,如果月份大于
且为闰年,答案需要
。
#include <bits/stdc++.h>
using namespace std;
int day[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int main() {
int y, m, d;
cin >> y >> m >> d;
int ans = d;
if (m >= 3 && (y % 4 == 0 && y % 100 != 0 || y % 400 == 0)) ans ++ ;
for (int i = 1; i < m; i ++ ) ans += day[i];
cout << ans << endl;
return 0;
}
变魔术
数组原本就相等时,不需要使用操作,反之可以找到一对钥匙,
,通过要是去调整其余数的大小,可以发现,不论是进行操作 1 还是操作 2 ,都不会改变数组中数字的奇偶个数,综上当两个数组中都纯在钥匙,且数组中所有数字奇数个数和偶数个数相同时,才有解决方案。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
void solve() {
int n;
cin >> n;
vector<int> a(n), b(n);
for (int i = 0; i < n; i ++ ) {
cin >> a[i];
}
for (int i = 0; i < n; i ++ ) {
cin >> b[i];
}
sort(a.begin(), a.end());
sort(b.begin(), b.end());
int flag = 1;
vector<int> cnt1(2, 0), cnt2(2, 0), f(2, 0);
for (int i = 0; i < n; i ++ ) {
if (a[i] != b[i]) flag = 0;
cnt1[a[i] % 2] ++ ;
cnt2[b[i] % 2] ++ ;
if (i && a[i] == a[i - 1] + 1) f[0] = 1;
if (i && b[i] == b[i - 1] + 1) f[1] = 1;
}
if (flag) cout << "Yes" << endl;
else if (f[0] && f[1] && cnt1[0] == cnt2[0] && cnt1[1] == cnt2[1]) cout << "Yes" << endl;
else cout << "No" << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int tt = 1;
cin >> tt;
while (tt--) {
solve();
}
return 0;
}
疯狂星期四
直接输出
。
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, a, m, b;
cin >> n >> a >> m >> b;
cout << n * a + m * b << endl;
return 0;
}

京公网安备 11010502036488号