题目链接:https://codeforces.ml/contest/1365/problem/A
一个1占一行一列。故可操作的次数为所剩行列的最小值。奇数先手胜
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define forn(i, l, r) for (int i = l; i < r; ++ i)
#define Forn(i, st, en) for (int i = st; i <= en; ++ i)
#define mset(a, x) memset(a, x, sizeof(a))
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mkp make_pair
#define paging cout << "-----------------" << endl
#define db1(x) cout << #x << " = " << x << endl
#define db2(x, y) cout << #x << " = " << x << ", " << #y << " = " << y << endl
#define lson (o << 1)
#define rson (o << 1 | 1)
#define FAST ios::sync_with_stdio(false); \
cin.tie(0) \
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef pair<int, int> pii;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1);
const double eps = 1e-6;
const int mod = 1e9 + 7;
const int N = 1e5 + 10;
void sol() {
int n, m; cin >> n >> m;
bool isRow[60], isCol[60];
mset(isRow, false);
mset(isCol, false);
int x;
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < m; ++ j) {
cin >> x;
if(x == 1) {isRow[i] = isCol[j] = true; }
}
}
int a = n, b = m;
for (int i = 0; i < n; ++ i) if(isRow[i]) -- a;
for (int i = 0; i < m; ++ i) if(isCol[i]) -- b;
x = min(a, b);
if(x & 1) cout << "Ashish" << endl;
else cout << "Vivek" << endl;
}
int main() {
FAST;
int _; cin >> _; while(_ --) sol();
return 0;
}
题目链接:https://codeforces.ml/contest/1365/problem/B
元素类型不同即可交换。若两种元素类型都存在,则各个元素之间可以随意交换,一定可以排成非降序列。
只有一种元素类型,则无法交换。是非降序列就Yes,不是就输出No。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define forn(i, l, r) for (int i = l; i < r; ++ i)
#define Forn(i, st, en) for (int i = st; i <= en; ++ i)
#define mset(a, x) memset(a, x, sizeof(a))
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mkp make_pair
#define paging cout << "-----------------" << endl
#define db1(x) cout << #x << " = " << x << endl
#define db2(x, y) cout << #x << " = " << x << ", " << #y << " = " << y << endl
#define lson (o << 1)
#define rson (o << 1 | 1)
#define FAST ios::sync_with_stdio(false); \
cin.tie(0) \
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef pair<int, int> pii;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1);
const double eps = 1e-6;
const int mod = 1e9 + 7;
const int N = 1e5 + 10;
int a[600];
void sol() {
int n; cin >> n; forn(i, 0, n) cin >> a[i];
int zero = 0, one = 0, b;
forn(i, 0, n) {
cin >> b;
if(b) ++ one;
else ++ zero;
}
if(zero != 0 && one != 0) cout << "Yes" << endl;
else {
forn(i, 1, n) if(a[i - 1] > a[i]) {
cout << "No" << endl;
return ;
}
cout << "Yes" << endl;
}
}
int main() {
FAST;
int _; cin >> _; while(_ --) sol();
return 0;
}
题目链接:https://codeforces.ml/contest/1365/problem/C
题意:两个序列a,b。同一序列的数字没有重复且都<=n。可以选择一个数字k,然后选择序列,使其左移或者右移。序列首尾相连。a1左移一位到an。an右移一位到a1。问怎样移动可以使满足a[i]=b[i]该条件的i最多
思路:移动步数< n ,故开一个2e5的数组cnt[]。确定移动序列,计算每个数字需要移动的步数,然后++cnt[步数]。左移与右移分别计算。找最大值。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define mset(a, x) memset(a, x, sizeof(a))
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mkp make_pair
#define paging cout << "-----------------" << endl
#define db1(x) cout << #x << " = " << x << endl
#define db2(x, y) cout << #x << " = " << x << ", " << #y << " = " << y << endl
#define lson (o << 1)
#define rson (o << 1 | 1)
#define FAST ios::sync_with_stdio(false); \
cin.tie(0)
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef pair<int, int> pii;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1);
const double eps = 1e-6;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;
int id1[N], id2[N];
int cnt[N];
void sol() {
int n; scanf("%d", &n);
int val;
for (int i = 1; i <= n; ++ i) {
scanf("%d", &val);
id1[val] = i;
}
for (int i = 1; i <= n; ++ i) {
scanf("%d", &val);
id2[val] = i;
}
int ans = 0;
mset(cnt, 0);
for (int i = 1; i <= n; ++ i) {
int a = id1[i];
int b = id2[i];
if(a >= b) ++ cnt[a - b];
else ++ cnt[a + n - b];
}
for (int i = 0; i < n; ++ i) ans = max(ans, cnt[i]);
mset(cnt, 0);
for (int i = 1; i <= n; ++ i) {
int a = id1[i];
int b = id2[i];
if(b >= a) ++ cnt[b - a];
else ++ cnt[b + n - a];
}
for (int i = 0; i < n; ++ i) ans = max(ans, cnt[i]);
printf("%d\n", ans);
}
int main() {
// int _; scanf("%d", &_); while(_ --) sol();
sol();
return 0;
}
题目链接:https://codeforces.ml/contest/1365/problem/D
用#将B的周围的四个格子围起来。然后从出口开始跑图,看看能不能找到所有的G。不能就输出No。如果B与G相连,那么围B同时也会围住G,此时可直接gg。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define forn(i, l, r) for (int i = l; i < r; ++ i)
#define Forn(i, st, en) for (int i = st; i <= en; ++ i)
#define mset(a, x) memset(a, x, sizeof(a))
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mkp make_pair
#define paging cout << "-----------------" << endl
#define db1(x) cout << #x << " = " << x << endl
#define db2(x, y) cout << #x << " = " << x << ", " << #y << " = " << y << endl
#define lson (o << 1)
#define rson (o << 1 | 1)
#define FAST ios::sync_with_stdio(false); \
cin.tie(0) \
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef pair<int, int> pii;
const int dir[4][3] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0} };
const int INF = 0x3f3f3f3f;
const double PI = acos(-1);
const double eps = 1e-6;
const int mod = 1e9 + 7;
const int N = 1e5 + 10;
int n, m;
char mat[60][60];
bool check(int x, int y) {
return (0 <= x && x < n) && (0 <= y && y < m);
}
void run(int x, int y) {
if(!check(x, y) || mat[x][y] == '#') return ;
mat[x][y] = '#';
forn (i, 0, 4) {
int nx = x + dir[i][0];
int ny = y + dir[i][1];
run(nx, ny);
}
}
void sol() {
scanf("%d%d", &n, &m);
forn (i, 0, n) scanf("%s", mat[i]);
bool ok = true;
forn (i, 0, n) forn(j, 0, m) if(mat[i][j] == 'B') forn (k, 0, 4) {
int nx = i + dir[k][0];
int ny = j + dir[k][1];
if(!check(nx, ny)) continue;
if(mat[nx][ny] == 'G') ok = false; // B、 G相连直接gg
else if(mat[nx][ny] != 'B') mat[nx][ny] = '#';
}
run(n - 1, m - 1);
forn (i, 0, n) forn (j, 0, m) if(mat[i][j] == 'G') ok = false;
if(ok) puts("Yes");
else puts("No");
}
int main() {
// FAST;
int _;
// cin >> _;
scanf("%d", &_);
while(_ --) sol();
return 0;
}
题目链接:https://codeforces.ml/contest/1365/problem/E
题意:一个序列a,子序列长度为k。子序列数的二进制形式,第i位为1的数有至少max(1, k - 2)个,那么ans+= 2的i次方。求ans的最大值
解法:一个长度为3的序列,当前值为ans3。现在往里面在加一个数num,我们会发现num对新的ans只会有负贡献无正贡献。k=4时,max(1, k - 2) = 2。若num的二进制中含有ans3中没有的高位1,但其个数为1,对ans无贡献。且有可能加上num后,原本ans3中的低位1个数不足2。对ans造成负贡献。故新的ans将<=ans3。继续加数同理,对ans不会有正贡献,故k到3即可。然后暴力循环找最大值。
当1<=k<=3的时候,此时的ans可以直接写成num1 | … | numk。
记得开ll。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define forn(i, l, r) for (int i = l; i < r; ++ i)
#define Forn(i, st, en) for (int i = st; i <= en; ++ i)
#define mset(a, x) memset(a, x, sizeof(a))
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mkp make_pair
#define paging cout << "-----------------" << endl
#define db1(x) cout << #x << " = " << x << endl
#define db2(x, y) cout << #x << " = " << x << ", " << #y << " = " << y << endl
#define lson (o << 1)
#define rson (o << 1 | 1)
#define FAST ios::sync_with_stdio(false); \
cin.tie(0) \
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef pair<int, int> pii;
const int dir[4][3] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0} };
const int INF = 0x3f3f3f3f;
const double PI = acos(-1);
const double eps = 1e-6;
const int mod = 1e9 + 7;
const int N = 1e5 + 10;
ll a[600];
void sol() {
int n; cin >> n; forn (i, 0, n) cin >> a[i];
ll ans = 0;
forn (i, 0, n) forn(j, i, n) forn (k, j, n) ans = max(ans, (a[i] | a[j] | a[k]) );
cout << ans << endl;
}
int main() {
FAST;
// int _;
// cin >> _;
// scanf("%d", &_);
// while(_ --)
sol();
return 0;
}
题目链接:https://codeforces.ml/contest/1365/problem/F
题意:两个序列,可交换序列的前后缀。前后缀的长度为k,1 <= k <= n / 2(向下取整)。问是否能使两个序列相同。
思路:显然下标为i,n - 1 - i(从0开始)的两个数字为一组。在前后缀的交换过程中,他们是相连的,其顺序也可交换。
例如:序列:1 2 3 4 5 6,交换2, 5。k的选取为2, 1, 2
k = 2, 5 6 3 4 1 2
k = 1, 2 6 3 4 1 5
k = 2, 1 5 3 4 2 6
每一组的位置可以随意交换,组内元素也可随意交换。故判断两序列的组是否相同即可。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define forn(i, l, r) for (int i = l; i < r; ++ i)
#define Forn(i, st, en) for (int i = st; i <= en; ++ i)
#define mset(a, x) memset(a, x, sizeof(a))
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mkp make_pair
#define paging cout << "-----------------" << endl
#define db1(x) cout << #x << " = " << x << endl
#define db2(x, y) cout << #x << " = " << x << ", " << #y << " = " << y << endl
#define lson (o << 1)
#define rson (o << 1 | 1)
#define FAST ios::sync_with_stdio(false); \
cin.tie(0) \
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef pair<int, int> pii;
const int dir[4][3] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0} };
const int INF = 0x3f3f3f3f;
const double PI = acos(-1);
const double eps = 1e-6;
const int mod = 1e9 + 7;
const int N = 1e5 + 10;
int a[600], b[600];
map<pii, int> pairs;
void sol() {
pairs.clear();
int n; cin >> n; forn (i, 0, n) cin >> a[i]; forn (i, 0, n) cin >> b[i];
bool ok = true;
if(n & 1 && a[n / 2] != b[n / 2]) ok = false;
forn (i, 0, n / 2) if(ok) {
pii p = mkp(min(a[i], a[n - 1 - i]), max(a[i], a[n - 1 - i]));
++ pairs[p];
}
forn (i, 0, n / 2) if(ok) {
pii p = mkp(min(b[i], b[n - 1 - i]), max(b[i], b[n - 1 - i]));
if(pairs[p] <= 0) ok = false;
-- pairs[p];
}
cout << (ok ? "Yes" : "No") << endl;
}
int main() {
FAST;
int _;
cin >> _;
// scanf("%d", &_);
while(_ --)
sol();
return 0;
}