A Array Divisibility
问题:
思路:注意到1.2.3.4.5.6....就是一组合法解
代码:
#include <bits/stdc++.h>
using namespace std;
void solve() {
int n;
cin >> n;
for(int i = 1; i <= n; i ++ ) cout << i << " ";
cout << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while(t -- ) {
solve();
}
return 0;
}
B cornor twist
问题:
思路:贪心的从第一行第一列开始构造出和b一样的数组,如果构造完后a != b则没有合法解
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 510;
int n, m;
char a[N][N];
char b[N][N];
void solve() {
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; i ++ ) {
for(int j = 1; j <= m; j ++ ) {
cin >> a[i][j];
}
}
for(int i = 1; i <= n; i ++ ) {
for(int j = 1; j <= m; j ++ ) {
cin >> b[i][j];
}
}
for(int i = 1; i <= n - 1; i ++ ) {
for(int j = 1; j <= m - 1; j ++ ) {
if(a[i][j] != b[i][j]) {
if(((a[i][j] + 1) % 3) == b[i][j]) {
(a[i][j] += 1) %= 3;
(a[i + 1][j + 1] += 1) %= 3;
(a[i][j + 1] += 2) %= 3;
(a[i + 1][j] += 2) %= 3;
} else {
(a[i][j] += 2) %= 3;
(a[i + 1][j + 1] += 2) %= 3;
(a[i][j + 1] += 1) %= 3;
(a[i + 1][j] += 1) %= 3;
}
}
}
}
bool flag = true;
for(int i = 1; i <= n; i ++ ) {
for(int j = 1; j <= m; j ++ ) {
if(a[i][j] != b[i][j]) flag = false;
}
}
if(flag) cout << "YES" << endl;
else cout << "NO" << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while(t -- ) {
solve();
}
return 0;
}
C have your cake eat it too
问题:
思路:就是对abc的一个排列组合,每组排列中做一下前缀和,嵌套个二分(不用二分直接暴力也行)
代码:
#include <bits/stdc++.h>
using namespace std;
void solve() {
int n;
cin >> n;
vector<long long> a(n + 1), b(n + 1), c(n + 1);
for(int i = 1; i <= n; i ++ ) {
cin >> a[i];
a[i] += a[i - 1];
}
for(int j = 1; j <= n; j ++ ) {
cin >> b[j];
b[j] += b[j - 1];
}
long long tot = 0;
for(int k = 1; k <= n; k ++ ) {
cin >> c[k];
tot += c[k];
c[k] += c[k - 1];
}
vector<int> ans(6);
auto check = [&](vector<long long> &a, vector<long long> &b, vector<long long> &c) {
int l = 1, r = n;
while(l < r) {
int mid = l + r >> 1;
if(a[mid] >= (tot + 2) / 3) r = mid;
else l = mid + 1;
}
if(a[l] >= (tot + 2) / 3 && l <= n - 2) {
ans[0] = 1;
ans[1] = l;
} else return false;
int tmp = l;
l ++, r = n;
while(l < r) {
int mid = l + r >> 1;
if(b[mid] - b[tmp] >= (tot + 2) / 3) r = mid;
else l = mid + 1;
}
if(b[l] - b[tmp] >= (tot + 2) / 3 && l <= n - 1) {
ans[2] = tmp + 1;
ans[3] = l;
} else return false;
tmp = l;
l ++, r = n;
while(l < r) {
int mid = l + r >> 1;
if(c[mid] - c[tmp] >= (tot + 2) / 3) r = mid;
else l = mid + 1;
}
if(c[l] - c[tmp] >= (tot + 2) / 3) {
ans[4] = tmp + 1;
ans[5] = l;
} else return false;
return true;
};
if(check(a, b, c)) {
for(auto t: ans) cout << t << " ";
cout << endl;
return;
} else if(check(a, c, b)) {
cout << ans[0] << " " << ans[1] << " " << ans[4] << " " << ans[5] << " " << ans[2] << " " << ans[3] << endl;
return;
} else if(check(b, a, c)) {
cout << ans[2] << " " << ans[3] << " " << ans[0] << " " << ans[1] << " " << ans[4] << " " << ans[5] << endl;
return;
} else if(check(b, c, a)) {
cout << ans[2] << " " << ans[3] << " " << ans[4] << " " << ans[5] << " " << ans[0] << " " << ans[1] << endl;
return;
} else if(check(c, a, b)) {
cout << ans[4] << " " << ans[5] << " " << ans[0] << " " << ans[1] << " " << ans[2] << " " << ans[3] << endl;
return;
} else if(check(c, b, a)) {
cout << ans[4] << " " << ans[5] << " " << ans[2] << " " << ans[3] << " " << ans[0] << " " << ans[1] << endl;
return;
} else cout << "-1" << endl;
}
int main() {
int t;
cin >> t;
while(t -- ) {
solve();
}
return 0;
}
D swap dilemma
问题:
思路:我们现在思考一个这样的问题:交换相距任意长度的元素是否都可以通过交换相邻元素实现,答案是一定的,自己模拟一下很容易就可以证明。那么现在交换相距任意距离的元素这个条件可以被我们替换成交换任意相邻元素。对于一组没有重复元素的序列,我们每一次交换相邻元素都会让该数组的逆序对数量 + 1或者 - 1也就是说,我们每一次操作都会使得ab两个数组逆序对数量的差值不变,或者减2,或者加2,如果我们可以让ab两个数组的逆序对数量相同,那么ab数组就可以相互转换,也就是如果ab逆序对数量和为偶数,数据就是合法的
这里逆序对可以用归并排序,也可以用树状数组
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 410;
const int M = 2e5 + 10;
long long g[N][N];
pair<int, int> b[M];
long long len[M];
int main() {
int n, m;
cin >> n >> m;
memset(g, 0x3f, sizeof g);
for(int i = 1; i <= m; i ++ ) {
long long v, u, t;
cin >> v >> u >> t;
b[i] = {v, u};
g[v][u] = min(g[v][u], t);
g[u][v] = min(g[u][v], t);
len[i] = t;
}
for(int i = 1; i <= n; i ++ ) g[i][i] = 0;
for(int k = 1; k <= n; k ++ ) {
for(int i = 1; i <= n; i ++ ) {
for(int j = 1; j <= n; j ++ ) {
g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
}
}
}
//cout << g[1][2] << endl;
int q;
cin >> q;
for(int o = 1; o <= q; o ++ ) {
int k;
cin >> k;
vector<int> c(k + 1);
long long tmp = 0;
for(int i = 1; i <= k; i ++ ) {
cin >> c[i];
tmp += len[c[i]];
}
long long ans = 1e18;
vector<pair<int, int>> a(k + 1);
function<void(int)> dfs = [&](int u) {
if(u == k + 1) {
//cout << "YES" << endl;
//for(auto t: a) cout << t.first << " " << t.second << endl;
long long res = 0;
res += g[1][a[1].first];
//cout << g[1][a[1].first] << endl;
res += g[a[k].second][n];
for(int i = 2; i <= k; i ++ ) {
res += g[a[i - 1].second][a[i].first];
}
ans = min(ans, res);
return;
}
for(int i = 1; i <= 2; i ++ ) {
if(i == 1) {
a[u].first = b[c[u]].first;
a[u].second = b[c[u]].second;
} else {
a[u].first = b[c[u]].second;
a[u].second = b[c[u]].first;
}
dfs(u + 1);
}
};
do {
dfs(1);
} while(next_permutation(c.begin() + 1, c.end()));
//for(int i = 1; i <= k; i ++ ) cout << c[i] << " ";
//cout << tmp <<endl;
cout << ans + tmp << endl;
}
return 0;
}
E