A.水盐平衡
要比较a/b和c/d的大小,可以比较a*d与b*c的大小
#include<bits/stdc++.h>
using namespace std;
void solve() {
int a, b, c, d;
cin >> a >> b >> c >> d;
int ans = (a * d) - (b * c);
if(ans > 0) {
cout << "S" << endl;
} else cout << "Y" << endl;
}
int main() {
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
B水平考试
不管单选还是多选,只要小蓝写的答案在正确答案中找不到就一定是0分,能找到就是10分(因为单选和多选的分都是一样的,多选没选全小灰灰会给小蓝补上正确答案)
#include<bits/stdc++.h>
using namespace std;
void solve() {
string s, f;
cin >> s >> f;
int flag = 1;
for(int i = 0; i < s.size(); i++) {
if(f.find(s[i]) == -1) {
flag = 0;
break;
}
}
if(flag) {
cout << 10 << endl;
} else cout << 0 << endl;
}
int main() {
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
C数组段数
2e5暴力显然超时,那我们可以用前缀和来记录,如果和前一个不一样那我们的前缀和数组就加加,一样就和前面的相等,查询的时候注意边界情况即可
#include<bits/stdc++.h>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<int> a(n + 1), cnt(n + 1);
cnt[0] = 0, cnt[1] = 1;
for(int i = 1; i <= n; i++) {
cin >> a[i];
}
for(int i = 2; i <= n; i++) {
cnt[i] = cnt[i - 1];
if(a[i] != a[i - 1]) cnt[i]++;
}
while(m--) {
int l, r;
cin >> l >> r;
int ans = 0;
if(a[l] == a[l - 1]) {
ans = cnt[r] - cnt[l - 1] + 1;
} else ans = cnt[r] - cnt[l - 1];
if(l == r) ans = 1;
cout << ans << endl;
}
return 0;
}
D剪纸游戏
bfs求坐标的xy最大值最小值,判断是否成矩阵。具体操作就是将走过的连一起的.中的最大的xy和最小的xy记录下来,判断(mx1-mi1 + 1)*(mx2-mi2 + 1)是否等于走过小正方形的数量,(mx1-mi1 + 1)*(mx2-mi2 + 1)代表最小的矩形,比如3*4的矩形你的x多走了1,那么必须还要走x那一行y的剩下三个格子,因为最大的x变成了4那么(mx1-mi1 + 1)*(mx2-mi2 + 1)会变成4*4,而我们每一次走过一个正方形小格我们的判断变量就是加加,最后判断是否和(mx1-mi1 + 1)*(mx2-mi2 + 1)的值相等,相等即为矩形,否则不是
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
typedef pair<int, int> PII;
queue<PII> q;
int n, m, mi1, mi2, mx1, mx2, cnt;
char s[1010][1010];
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
void bfs(int x, int y) {
q.push({x, y});
cnt = 1;
mx1 = max(mx1, x);
mx2 = max(mx2, y);
mi1 = min(mi1, x);
mi2 = min(mi2, y);
while(!q.empty()) {
auto t = q.front();
q.pop();
mx1 = max(mx1, t.fi);
mx2 = max(mx2, t.se);
mi1 = min(mi1, t.fi);
mi2 = min(mi2, t.se);
for(int i = 0; i < 4; i++) {
int x = t.fi + dx[i];
int y = t.se + dy[i];
if(x < 1 || x > n || y < 1 || y > m) continue;
if(s[x][y] == '*') continue;
s[x][y] = '*';
cnt++;
q.push({x, y});
}
}
}
int main() {
mi1 = 1e9, mi2 = 1e9;
mx1 = 0, mx2 = 0;
cin >> n >> m;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
cin >> s[i][j];
}
}
int ans = 0;
cnt = 0;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
if(s[i][j] == '.') {
bfs(i, j);
if(cnt > 1) cnt--;
if(cnt == (mx1 - mi1 + 1) * (mx2 - mi2 + 1)) ans++;
mi1 = 1e9, mi2 = 1e9;
mx1 = 0, mx2 = 0;
}
}
}
cout << ans << endl;
return 0;
}
E可口蛋糕
二分结合后缀最大子串和,有道差不多的题,很经典的算法。最大子串和 (nowcoder.com)
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 5;
int w[N], d[N], s1[N], s2[N], lt[N];
signed main() {
int n, W;
cin >> n >> W;
for(int i = 1; i <= n; i++) {
cin >> w[i];
s1[i] = s1[i - 1] + w[i];
}
for(int i = 1; i <= n; i++) {
cin >> d[i];
s2[i] = s2[i - 1] + d[i];
}
lt[n] = max(d[n], 0ll);
for(int i = n - 1; i >= 1; i--) {
lt[i] = max(0ll, lt[i + 1] + d[i]);
}
int ans = s2[n];
for(int i = 1; i <= n; i++) {
if(s1[n] - s1[i - 1] < W) continue;
int l = i, r = n;
while(l < r) {
int mid = (l + r) >> 1;
if(s1[mid] - s1[i - 1] >= W) r = mid;
else l = mid + 1;
}
ans = max(ans, s2[r] - s2[i - 1] + lt[r + 1]);
}
cout << ans << endl;
return 0;
}