A. Shortest Path with Obstacle
题意:给出三个点坐标A,B,C,求在不经过C点的条件下,A->B的最短路径长度
思路:首先考虑一般情况,ans = abs(xa - xb) + abs(ya - yc),判断C是否与A、B共线的同时且在A、B中间,这种情况需要ans+2.
代码:
inline void solve() {
ll xa, ya, xb, yb, xc, yc;
cin >> xa >> ya >> xb >> yb >> xc >> yc;
ll ans = abs(xa - xb) + abs(ya - yb);
if(xa == xb && xb == xc && yc <= max(ya, yb) && yc >= min(ya, yb))
ans += 2;
else if(ya == yb && yb == yc && xc <= max(xa, xb) && xc >= min(xa, xb))
ans += 2;
cout << ans << endl;
return ;
}
B. Alphabetical Strings
题意:一个字符串如果满足以下的构造方法,则输出Yes,否则输出No。
①:字符串s一开始为空
②:第i步可以将字母表中的第i大的字符添加到s的首或者尾
③:重复进行第2步,直到最后返回字符串s
思路:不满足条件的字符串有以下特征
①:出现的字母不满足能添加的字母
②:s[i]应该小于其中一个相邻的字母
③:s[i]出现次数应该只有一次
代码
inline void solve() {
string s; cin >> s;
map<char, ll> cnt;
for(int i = 0; i < s.size(); i++) {
cnt[s[i]]++;
if(cnt[s[i]] == 2 || i - 1 >= 0 && i + 1 < s.size() && s[i] > s[i - 1] && s[i] > s[i + 1] || s[i] >= s.size() + 'a') {
cout << "No" << endl;
return ;
}
}
cout << "Yes" << endl;
return ;
}
C. Pair Programming
题意:一个文本,初始有k行,两个人A,B,各自有n,m次操作x,当x==0时添加一行,当x>0时,改变第x行,并且只能一个接一个进行操作,求一个合法操作序列。
思路:直接模拟即可
代码:
#include <bits/stdc++.h>
using namespace std;
#define _for(i, a, b) for(register int i = a; i <= b; i++)
typedef long long ll;
typedef pair<ll, ll> pii;
const ll N = 1e7 + 10, mod = 1e9 + 7, inf = 0x3f3f3f3f3f3f3f3f;
ll t, n, m, k, a[N], b[N];
unordered_map<ll, ll> mp;
inline void solve() {
cin >> k >> n >> m;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int j = 1; j <= m; j++) cin >> b[j];
vector<ll> ans; ans.clear();
int i = 1, j = 1;
while(i <= n && j <= m) {
if(a[i] == 0) {
ans.push_back(0);
i++; k++;
continue;
}
else if(b[j] == 0) {
ans.push_back(0);
j++; k++;
continue;
}
if(a[i] <= b[j]) {
if(a[i] <= k) {
ans.push_back(a[i]);
i++;
}
else {
cout << -1 << endl;
return ;
}
}
else {
if(b[j] <= k) {
ans.push_back(b[j]);
j++;
}
else {
cout << -1 << endl;
return ;
}
}
}
while(i <= n) {
if(a[i] <= k) {
ans.push_back(a[i]);
if(a[i] == 0) k++;
i++;
}
else {
cout << -1 << endl;
return ;
}
}
while(j <= m) {
if(b[j] <= k) {
ans.push_back(b[j]);
if(b[j] == 0) k++;
j++;
}
else {
cout << -1 << endl;
return ;
}
}
for(int i = 0; i < ans.size() - 1; i++) cout << ans[i] << " "; cout << ans[ans.size() - 1] << endl;
return ;
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> t;
while(t--)
solve();
return 0;
}
D. Co-growing Sequence
题意:给出数字序列A,求数字序列B,满足①:字典序最小,②:C = A^B,其中C[i] & C[i-1] = C[i]
思路:
①:C[i] = A[i] ^ B[i];②C[i - 1] & C[i] = C[i - 1];
由①②推出③:C[i - 1] & (A[i] ^ B[i]) = C[i - 1].
由于字典序要求最小,所以对于C[i - 1]的每一位二进制数为1时,也必须满足A[i] ^ B[i]对应的二进制数也为1。
代码
inline void solve() {
cin >> n;
vector<ll> a(n),b(n),c(n);
for(int i = 0; i < n; i++) cin >> a[i];
b[0] = 0; c[0] = a[0];
for(int i = 1; i < n; i++) {
for(int j = 0; j < 30; j++) {
int k = c[i - 1] >> j & 1;
int f = a[i] >> j & 1;
if(k == 1 && f == 0)
b[i] += (1 << j);
}
c[i] = a[i] ^ b[i];
}
for(int i = 0; i < n; i++) cout << b[i] << " "; cout << endl;
return ;
}
E. Air Conditioners
题意:n个方格横向排列,k个空调,每个空调有一个温度,每个方格的温度计算公式为,求n个方格的温度分别为多少。
思路:分别从前往后,再从后往前,记录每一个方格的最小温度即可
代码:
inline void solve() {
int n, k; cin >> n >> k;
vector<int> v(k), x(k);
unordered_map<int, int> pos;
for(int i = 0; i < n; i++) pos[i] = inf;
for(int i = 0; i < k; i++)
cin >> x[i];
for(int i = 0; i < k; i++) {
cin >> v[i];
pos[x[i] - 1] = v[i];
}
for(int i = 1; i < n; i++)
pos[i] = min(pos[i - 1] + 1, pos[i]);
for(int i = n - 2; i >= 0; i--)
pos[i] = min(pos[i + 1] + 1, pos[i]);
for(int i = 0; i < n; i++)
cout << pos[i] << " ";
cout << endl;
return ;
}