我觉得思维题其实真的很重要
1200才计rating,虽然我打的也很菜。
我感觉atcoder的分比较实,希望寒假把 atcoder也打上去
A - atcoder < S
Given is a string \(S\) consisting of lowercase English letters. Snuke can do the operation of swapping two adjacent characters in SS. For example, if \(S\) ==
agc, one operation can change it togac(by swappingaandg) oracg(by swappinggandc).Snuke wants to do this operation zero or more times so that
atcoder< \(S\) holds lexicographically.Determine whether the objective is achievable. If it is achievable, find the minimum number of operations needed.
错误的思路:
for _ in range(int(input())):
  s = input()
  ans = -1
  for i in range(len(s)):
    if s[i] != ‘a‘:
      ans = i
      break
  print(ans)
B-Bracket Score

开始的时候一直想着怎么遍历全部的括号组合。
后来意识到应该从 \(A\) ,\(B\) 去入手
假定最先全部选择 \(A\)
然后 \(B_i = B_i - A_i\)
问题就转化成了在新的数组 \(B\) 里选择一对一对的括号使得和最大。
每次选择 \(B_i\) 和 \(B_j\) 必须有 \(j-i+1\) 是偶数
后面发现好像可以随便选
关于这点比较玄学, 我发现只要选择了一样多的偶数和奇数,总是能找到一种方式让他们是合法的括号序列,目前还没有想到怎么证明这个的正确性
于是就分成奇数和偶数
排个序,一直选
int main(){
    cin >> n;
    long long ans = 0;
    for(int i = 1;i <= n;i++)cin >> A[i],ans += A[i];
    for(int i = 1;i <= n;i++)cin >> B[i],B[i] -= A[i];
    vector<int>a,b;
    for(int i = 1;i <= n;i++){
        if(i & 1)a.push_back(B[i]);
        else b.push_back(B[i]);
    }
    sort(a.begin(),a.end(),greater<int>());
    sort(b.begin(),b.end(),greater<int>());
    for(int i = 1;i <= n/2;i++){
        if(a[i-1] + b[i-1] > 0){
            ans += a[i-1] + b[i-1];
        }
    }
    cout << ans << endl;
    
}
C-Penguin Skating

说实话这个游戏我好像在哪玩过...
或者自己之前脑子里想过这个游戏
但还是没有 A 出来
样例二大概就是这么个情况
| O | O | O | O | O | O | O | O | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| X | X | X | X | X | X | X | X | 
假策略:
先对AB排序
然后从前往后扫
若
A[i] == B[i]则跳过若
A[i] > B[i],则看
B[i]-1的位置有没有??或墙,或则第i-1只?? 没移动之前 是否在B[i]-1的位置(可以先借用第i-1只??当墙,然后第i-1只再归位)例如
O O O X X X 否则无解
若
A[i] < B[i]往后面扫,若
A[i+p] - p == B[i]则把p个全部往后推否则无解
O O O O X X X X #include<bits/stdc++.h> using namespace std; const int N = 2e5 + 10; int A[N], B[N], n, k; int main() { cin >> n >> k; A[0] = 0; B[0] = 0; A[n + 1] = k + 1; B[n + 1] = k + 1; for (int i = 1; i <= n; i++)cin >> A[i]; for (int i = 1; i <= n; i++)cin >> B[i]; sort(A, A + 2 + n); sort(B, B + 2 + n); int ans = 0; int pre = 0; for (int i = 1; i < n + 2; i++) { int now = A[i]; if (A[i] > B[i]) { if (pre + 1 == B[i] or A[i - 1] + 1 == B[i]) { ans++; A[i] = B[i]; } else { cout << -1 << endl; return 0; } } else if (A[i] < B[i]) { int f = 0; int p; for (p = 1; i + p < n + 2; p++) { if (A[i + p] - p == B[i]) { f = 1; break; } } if (f) { for (int j = 0; j < p; j++) { A[i + j] = B[i] + j; } ans += p; } else { cout << -1 << endl; return 0; } } pre = now; } cout << ans << endl; }
正解
考虑??之间的空方块, \(x_0,....,x_n\)
每次操作就是 \(x_i := 0 ,\ x_{i+1} += x_i\)
实在是妙
/*
 * @Author: zhl
 * @Date: 2020-10-19 10:49:39
 */
#include<bits/stdc++.h>
#define max(a,b) (a>b?a:b)
#define int long long
using namespace std;
const int N = 1e5 + 10;
int A[N], B[N];
int n, k;
signed main() {
	cin >> n >> k;
	A[n + 1] = B[n + 1] = k + 1;
	for (int i = 1; i <= n; i++)cin >> A[i];
	for (int i = 1; i <= n; i++)cin >> B[i];
	for (int i = n + 1; i >= 1; i--) {
		A[i] = A[i] - A[i - 1] - 1;
		B[i] = B[i] - B[i - 1] - 1;
	}
	int ans = 0;
	int j = 1;
	for (int i = 1; i <= n + 1; i++) {
		if (!B[i])continue;
		while (!A[j])j++;
		int sum = 0; int st = j;
		while (sum < B[i] and j <= n + 1)sum += A[j++];
		if (sum != B[i]) {
			puts("-1"); return 0;
		}
		int ed = j - 1;
		ans += max(0, i - st) + max(0, ed - i);
	}
	cout << ans << endl;
}
原文:https://www.cnblogs.com/sduwh/p/13839124.html