D
#include <bits/stdc++.h> using namespace std; char g[10][10]; int main() { for (int i = 1; i <= 5; i ++) scanf("%s", g[i] + 1);//这样可以保证下标都从1开始 for (int i = 1; i <= 4; i ++) for (int j = 1; j <= 4; j ++) if (g[i][j] == '*' && g[i][j + 1] == '*' && g[i + 1][j] == '*' && g[i + 1][j + 1] == '*') { cout << "Yes" << endl; return 0; } cout << "No" << endl; return 0; }
E
题目保证有序情况下不重复,直接 j 从 i 开始, k 从 j 开始就行了
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int ans = 0; int s, t; cin >> s >> t; for (int i = 0; i <= s; i ++) for (int j = i; j + i <= s; j ++) for (int k = j; i + j + k <= s; k ++) if (i * j * k <= t) ans ++; cout << ans << endl; return 0; }
G
可以发现答案应该是1 * 1 + 2 * 2 + ... n * n,但是因为 n 最大值是 1e9,直接 for 循环会 TLE,所以需要推公式,公式就是
但是还有一些问题,int的最大值是2e9, n 若为 int 型, 1e9 * 1e9会爆 int,所以需要 long long存储,但是三个 1e9 级别的相乘还是会爆 long long,所以要提前取模一下
#include <bits/stdc++.h> using namespace std; const int mod = 1e9 + 7; int main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); LL n; cin >> n; cout << n * (n + 1) % mod * (2 * n + 1) % mod; return 0; }
H
大模拟题
STL版本
#include <bits/stdc++.h> using namespace std; const int N = 205; int main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int t; cin >> t; while (t --) { int n, m; cin >> n >> m; set<int> col[N]; for (int i = 1; i <= n; i ++) for (int j = 1; j <= m; j ++) { int x; cin >> x; col[i].insert(x); } vector<int> v; for (int i = 1; i <= n; i ++) v.push_back(i); while (m --) { int c; cin >> c; vector<int> temp; for (int x : v) { if (col[x].count(c)) temp.push_back(x); } v = temp; cout << v.size() << ' '; } cout << endl; } return 0; }
数组版本
g 数组存第 i 件礼物有没有第 j 种颜色, st 数组为false的是存满足目前条件的礼物,为true的是不满足条件的礼物,每次从之前满足条件的礼物里面筛选
#include <bits/stdc++.h> using namespace std; const int N = 205; bool g[N][N], st[N]; int main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int t; cin >> t; while (t --) { int n, m; cin >> n >> m; memset(g, 0, sizeof g); memset(st, 0, sizeof st); for (int i = 1; i <= n; i ++) for (int j = 1; j <= m; j ++) { int x; cin >> x; g[i][x] = true; } while (m --) { int c; cin >> c; int ans = 0; for (int i = 1; i <= n; i ++) if (!st[i]) { if (g[i][c]) ans ++; else st[i] = true; } cout << ans << ' '; } cout << endl; } return 0; }
I
博弈题,首先思考若两者都没有技能卡,那么是不是最后一个回合谁操作谁输,那么如何求出有多少回合呢,由于 n 高达1e16,枚举肯定会TLE,那么直接用二分来求解有多少回合
这里(#define LL long long了,写起来更方便)
LL l = 1, r = 1e8; while (l < r) { LL mid = l + r >> 1; LL x = mid * (mid + 1) / 2; if (x <= n) l = mid + 1; else r = mid; }
那么因为第一回合牛妹操作,那么如果有奇数个回合是不是牛妹就输了,有偶数个回合是不是牛牛就输了
现在考虑双方都有技能卡的情况,那么一个人的技能卡是可以抵消另一个人的技能卡的,所以可以类比为只有一个人可以发动技能或者都发动不了(双方技能卡数量相等)
那么就比如最后一回合是我输了,那么我如果技能卡比另一个多,那么我就可以使用技能卡,让另一个人输
那么就比如最后一回合是另一个输,那么我要保证我技能卡大于等于另一个人的技能卡,使他发不出技能,保证我赢
#include <bits/stdc++.h> using namespace std; #define LL long long int main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int T; cin >> T; while (T --) { LL n, a, b; cin >> n >> a >> b; LL len; LL l = 1, r = 1e8; while (l < r) { LL mid = l + r >> 1; LL x = mid * (mid + 1) / 2; if (x <= n) l = mid + 1; else r = mid; } len = r; if (len & 1) { if (a >= b) cout << "niuniu" << endl; else cout << "niumei" << endl; } else { if (a > b) cout << "niuniu" << endl; else cout << "niumei" << endl; } } return 0; }
J
很简单,可以发现若横纵坐标之和为奇数那么就找不到
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int T; cin >> T; while (T --) { int x, y; cin >> x >> y; if (x + y & 1) cout << -1 << ' ' << -1 << endl; else if (x & 1) { if (x > y) cout << (x + y) / 2 << ' ' << 0 << endl; else cout << 0 << ' ' << (x + y) / 2 << endl; } else cout << x / 2 << ' ' << y / 2 << endl; } return 0; }
K
模拟题
#include <bits/stdc++.h> using namespace std; #define LL long long const int N = 1e5 + 5; int n, k; string strs[N]; unordered_map<string, int> mp; int main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); cin >> n >> k; for (int i = 1; i <= n; i ++) cin >> strs[i]; LL ans = 0; for (int i = 1; i <= n; i ++) { if (i - k - 2 >= 1) mp[strs[i - k - 2]] --; ans += mp[strs[i]]; mp[strs[i]] ++; } cout << ans << endl; return 0; }
M
可以发现答案就是周长,图形可能是个非常规图形,但是因为边一定是要么平行于 x 轴要么平行于 y 轴, 那么看本题的说明
其实把边平移一下,求周长可以平移为求外面最大的矩形的周长,那么只需要找到最上面的羊的坐标,最下面的羊的坐标,以及最左边和最右边的羊的坐标
由于最终结果可能是2 * 1e9 * 1e9是会爆 int 的,所以需要在计算过程种插入long long型, 所以用 2ll 去乘
#include <bits/stdc++.h> using namespace std; int n, m, k; int a, b, c, d; int l, r, up, down; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> m >> k; cin >> a >> b >> c >> d; l = a, r = c, up = d, down = b; while (k --) { int x, y; cin >> x >> y; l = min(l, x), r = max(r, x + 1); down = min(down, y), up = max(up, y + 1); } long long ans = 2ll * (up - down + r - l); cout << ans << endl; return 0; }
N
思维题
最不好想的一点就是最小的数为 1 的情况,想到了就对了
#include <bits/stdc++.h> using namespace std;int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t; cin >> t; while (t --) { int a[3]; cin >> a[0] >> a[1] >> a[2];
sort(a, a + 3); if (a[0] == a[1] || a[1] == a[2]) cout << 1 << endl; else if (a[1] + a[0] == a[2] || a[1] * a[0] == a[2] || a[1] == a[0] * 2 || a[2] == a[1] * 2 || a[2] == a[0] * 2 || a[0] == 1) cout << 2 << endl; else cout << 3 << endl; } return 0; }
O
先看题目下面的说明了解大概
如果原本 a 数组就等于 b 数组,那么他肯定一个药丸都不吃
那么只要有一个不相等,他就需要吃药丸,就考虑最坏情况呗,他把 n 种使得 a[i] 远离 b[i] 都吃了一次,所以答案应该是 ∑ abs(a[i] + b[i]) + 1 + 1,因为他还需要多吃一次抵消掉上次的远离
#include <bits/stdc++.h> using namespace std;
#define LL long long const int N = 1e5 + 5; int n; int a[N], b[N]; int main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); cin >> n; for (int i = 1; i <= n; i ++) cin >> a[i]; for (int i = 1; i <= n; i ++) cin >> b[i]; bool flag = true; for (int i = 1; i <= n; i ++) if (a[i] != b[i]) { flag = false; break; } if (flag) { cout << 0 << endl; return 0; } LL ans = 0; for (int i = 1; i <= n; i ++) ans += abs(a[i] - b[i]) + 2; cout << ans << endl; return 0; }
标签:农业大学,int,题解,nullptr,cin,long,训练赛,tie,cout From: https://www.cnblogs.com/Leocsse/p/17028541.html