#include<bits/stdc++.h> using namespace std; #define int long long signed main() { string a, b; int t, pre = -1, k = 0, ans = 0; while (cin >> a >> b >> t) { if (a != b) { k = 0; pre = t; continue; } if (pre == -1)k = 1; else { if (t - pre <= 1000)k++; else k = 1; } pre = t; if (k > ans)ans = k; } cout << ans << endl; return 0; }
#include<bits/stdc++.h> using namespace std; #define ll long long ll n, m, ans; bool chk(ll k) { int s = 0; while(k) { s += k & 1; k >>= 1; } if(s == 1)return true; return false; } int main() { cin >> n; for(int i = 1;i <= n;i ++) { cin >> m; if(chk(m))ans ++; } cout << ans << endl; }
for(int i = 1; i <= m / 2; i++) { int bl = l[i] + r[m - 2 * i]; int br = r[i] + l[m - 2 * i]; cnt = max(cnt, max(bl, br)); }
ad.为什么是一次折返?
1) 证明
假设某路径存在两次折返(比如:正负正),轨迹可拆解成:
正走 i 步 → 负走 j 步 → 正走 k 步(i + j + k = m)
覆盖区间是:正轴 [0, i] ∪ 负轴 [0, j] ∪ 正轴 [0, k]
但是我们同等的步数转换成一次折返的话:
正走 (i+j) 步 → 调头后正走 k 步(总步数:(i+j) + k = m)
此时覆盖区间为:正轴 [0, i + j] ∪ 正轴 [0, k],很显然,覆盖范围更广,两次折返的重复区间会抵消很多有效区间
2) 反证
假设有最优路径 P 包含 k 次折返(k>=2)
对比:
综上,P' 比 P 多出 2(k-1) 步,所以 P 不可能是最优解
P' 总消耗:x + y ≤ m(P 至少消耗 x + y + 2(k-1) 步,因每次调转需折返)
调头后负走 y 步(覆盖负轴 [0, y])
直接正走 x 步(覆盖正轴 [0, x])
新路径 P':
设 P 在正轴最远到达 x,负轴最远到达 y
二。坑
矿石是一次性的,反复来回不能得到多个矿石
原点的矿石是一开始就有的,但是也要考虑
主要就是读题的问题,不过比较容易有疏漏
#include<bits/stdc++.h> using namespace std; #define int long long const int N = 2e6 + 9;//注意这个存储的是矿石的计数,所以开的是 m 是常量而非 n 的常量 int l[N], r[N]; signed main() { ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int n, m;cin >> n >> m; int z = 0; for(int i = 0; i < n; i++) // 修改循环起始条件 { int x;cin >> x; if(abs(x) <= m && x < 0)l[-x] ++; else if(abs(x) <= m && x > 0)r[x] ++; else if(x == 0)z ++; } for(int i = 1; i <= m; i++) { l[i] += l[i - 1]; r[i] += r[i - 1]; } int cnt = max(l[m], r[m]); for(int i = 1; i <= m / 2; i++) { int bl = l[i] + r[m - 2 * i]; int br = r[i] + l[m - 2 * i]; cnt = max(cnt, max(bl, br)); } cnt += z; cout << cnt << endl; return 0; }
思维转换上一个比较重要的点,题目说的是要从 S 的开头添加字符,也就是只能从字符串的左边补,如果直接把题目转化成两边互消的话,就错了。
#include<bits/stdc++.h> using namespace std; const int N = 1e6 + 9; int T, n; char s[N]; bool check(char c) {return c == 'l' || c == 'q' || c == 'b';} bool check(int l, int r) { while (l < r) if (s[l++] != s[r--]) return false; return true; } int main() { ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); cin >> T; while (T--) { cin >> (s + 1); n = strlen(s + 1); int l, r; for (l = 1; l <= n; ++l) if (!check(s[l])) break; if (l == n + 1) { cout << "Yes" << "\n"; continue; } for (r = n; r;r --) if (!check(s[r])) break; if (l - 1 > n - r || !check(l, r)) { cout << "No" << "\n"; continue; } l --, r ++; bool tag = true; while (l && r <= n) { if (s[l] != s[r]) { tag = false; break; } l --, r ++; } if (tag) cout << "Yes" << "\n"; else cout << "No" << "\n"; } return 0; }