Codeforces Round #648 (Div. 2)
A. Matrix Game
简单博弈(贪心?)。
Code
/*
* Author: heyuhhh
* Created Time: 2020/6/7 22:39:24
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
void run() {
int n, m; cin >> n >> m;
vector <vector <int>> a(n, vector <int>(m));
vector <int> cols(m), rows(n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> a[i][j];
if (a[i][j]) {
++cols[j];
++rows[i];
}
}
}
int cntr = 0, cntl = 0;
for (int i = 0; i < n; i++) {
if (rows[i] == 0) ++cntr;
}
for (int i = 0; i < m; i++) {
if (cols[i] == 0) ++cntl;
}
int t = min(cntr, cntl);
if (t & 1) {
cout << "Ashish" << '\n';
} else {
cout << "Vivek" << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T; while(T--)
run();
return 0;
}
B. Trouble Sort
注意到\(b\)中至少有一个\(0\),一个\(1\)必然可以任意排序;否则直接判断一下即可。
Code
/*
* Author: heyuhhh
* Created Time: 2020/6/7 22:44:07
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
void run() {
int n; cin >> n;
vector <int> a(n), b(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
for (int i = 0; i < n; i++) {
cin >> b[i];
}
sort(all(b));
for (int i = 1; i < n; i++) {
if (b[i] != b[i - 1]) {
cout << "Yes" << '\n';
return;
}
}
for (int i = 1; i < n; i++) {
if (a[i] < a[i - 1]) {
cout << "No" << '\n';
return;
}
}
cout << "Yes" << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T; while(T--)
run();
return 0;
}
C. Rotation Matching
求位置差值出现次数最多个数即可。
Code
/*
* Author: heyuhhh
* Created Time: 2020/6/7 23:22:04
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
void run() {
int n; cin >> n;
vector <int> a(n), b(n);
vector <vector <int>> v(n + 1);
for (int i = 0; i < n; i++) {
cin >> a[i];
v[a[i]].push_back(i);
v[a[i]].push_back(i + n);
}
vector <int> cnt(n);
for (int i = 0; i < n; i++) {
cin >> b[i];
for (auto it : v[b[i]]) {
if (it >= i && it - i < n) {
++cnt[it - i];
}
}
}
int ans = *max_element(all(cnt));
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
D. Solve The Maze
贪心堵住坏人,然后从终点出发bfs即可。
细节见代码:
Code
/*
* Author: heyuhhh
* Created Time: 2020/6/7 23:29:38
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
void run() {
int n, m; cin >> n >> m;
vector <string> mz(n);
int cnt = 0;
for (int i = 0; i < n; i++) {
cin >> mz[i];
for (int j = 0; j < m; j++) {
if (mz[i][j] == 'G') ++cnt;
}
}
if (cnt == 0) {
cout << "Yes" << '\n';
return;
}
const int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};
auto ok = [&] (int x, int y) {
return x >= 0 && x < n && y >= 0 && y < m;
};
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (mz[i][j] == 'B') {
for (int k = 0; k < 4; k++) {
int x = i + dx[k], y = j + dy[k];
if (ok(x, y)) {
if (mz[x][y] == '#') {}
if (mz[x][y] == '.') mz[x][y] = '#';
if (mz[x][y] == 'B') {}
if (mz[x][y] == 'G') {
cout << "No" << '\n';
return;
}
}
}
}
}
}
if (mz[n - 1][m - 1] == '#') {
cout << "No" << '\n';
return;
}
vector <vector <int>> d(n, vector <int>(m, -1));
queue <pii> q;
q.push(MP(n - 1, m - 1));
d[n - 1][m - 1] = 0;
while (!q.empty()) {
pii now = q.front(); q.pop();
int x = now.fi, y = now.se;
for (int k = 0; k < 4; k++) {
int nx = x + dx[k], ny = y + dy[k];
if (ok(nx, ny) && mz[nx][ny] != '#') {
if (d[nx][ny] == -1) {
d[nx][ny] = d[x][y] + 1;
q.push(MP(nx, ny));
}
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (mz[i][j] == 'B' && d[i][j] != -1) {
cout << "No" << '\n';
return;
}
if (mz[i][j] == 'G' && d[i][j] == -1) {
cout << "No" << '\n';
return;
}
}
}
cout << "Yes" << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T; while(T--)
run();
return 0;
}
E. Maximum Subsequence Value
注意到\(k>3\)的时候解一定没有前面优,大概的证明可以看看视频,如果有更优的那么之前的也能最优。
所以只用考虑\(k\leq 3\)的情况,所以\(O(n^3)\)枚举就行。
Code
/*
* Author: heyuhhh
* Created Time: 2020/6/7 23:56:36
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
void run() {
int n; cin >> n;
vector <ll> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
if (n == 1) {
cout << a[0] << '\n';
return;
}
ll ans = *max_element(all(a));
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
ans = max(ans, (a[i] | a[j]));
}
}
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
for (int k = j + 1; k < n; k++) {
ans = max(ans, (a[i] | a[j]) | a[k]);
}
}
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
F. Swaps Again
注意到对称位置上的数经过若干次操作过后位置也是对称的。
所以直接\(O(n^2)\)模拟就行。
Code
/*
* Author: heyuhhh
* Created Time: 2020/6/8 0:58:57
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
void run() {
int n; cin >> n;
vector <int> a(n), b(n), c(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
for (int i = 0; i < n; i++) {
cin >> b[i];
}
vector <bool> vis(n);
for (int i = 0; i < n / 2; i++) {
int j = n - i - 1;
for (int k = 0; k < n; k++) {
if (!vis[k]) {
if (a[i] == b[k] && a[j] == b[n - k - 1]) {
c[k] = a[i];
c[n - k - 1] = a[j];
vis[k] = vis[n - k - 1] = true;
break;
}
}
}
}
if (n & 1) {
c[n / 2] = a[n / 2];
}
for (int i = 0; i < n; i++) {
if (c[i] != b[i]) {
cout << "No" << '\n';
return;
}
}
cout << "Yes" << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T; while(T--)
run();
return 0;
}
G. Secure Password
\(val[i][0/1]\)表示当下标中第\(i\)个二进制位为\(0/1\),其余任意时,所有数或起来的值。
那么对于每个下标可以每个二进制位单独计算,最后总的值或起来即是答案。
但这种思路我们会询问\(2logn\)次,显然会超过\(13\),考虑只用\(val[i][0]\)或者\(val[i][1]\)来进行表示,这样询问次数满足条件,但是不能处理下标之间包含的关系,比如\((i\& j=i)\)这种。
考虑将每个下标进行映射,映射过后任意两个下标都不存在包含与被包含的关系并且互不相等,此时可以只用\(val[i][0]\)或者\(val[i][1]\)得到答案。
我们可以将每个数映射为包含\(6\)个\(1\)的二进制数,\({13\choose 6}=1716>1000\),所以这样肯定能够映射完所有的数的,之后直接对每个下标求解答案即可。
询问次数至少为\(logn\)次。
映射的这步十分巧妙!!其实前面的思路还比较好想,关键就是后面这里,神仙。。
细节见代码:
Code
/*
* Author: heyuhhh
* Created Time: 2020/6/8 19:27:10
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1000 + 5, P = 13;
void run() {
int n;
cin >> n;
vector <vector <int>> bit(P);
vector <int> change(n);
int k = 0;
for (int i = 0; i < 1 << P; i++) {
if (__builtin_popcount(i) != P / 2) continue;
for (int j = 0; j < P; j++) {
if (!(i >> j & 1)) {
bit[j].push_back(k + 1);
}
}
change[k++] = i;
if (k == n) break;
}
auto query = [&] (vector <int>& q) {
cout << '?' << ' ' << sz(q);
for (auto it : q) {
cout << ' ' << it;
}
cout << '\n' << endl;
ll t; cin >> t;
return t;
};
vector <ll> val(P);
for (int i = 0; i < P; i++) {
if (sz(bit[i])) {
val[i] = query(bit[i]);
}
}
vector <ll> A(n);
for (int i = 0; i < n; i++) {
int x = change[i];
for (int j = 0; j < P; j++) {
if (x >> j & 1) {
A[i] |= val[j];
}
}
}
cout << "!";
for (int i = 0; i < n; i++) {
cout << ' ' << A[i];
}
cout << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
重要的是自信,一旦有了自信,人就会赢得一切。