题意可以说是非常简单的,我们选定的格子的行列都不能存在1,可以发现我们可以放的格子一定是固定的,然后这题就变成了技术总共可以放多少个棋子了,所以我们直接开两个数组记录一下行列是否有1存在,再通过暴力求解的到可放的格子的数量就行,具体看代码注释吧。
#include
using namespace std;
typedef long long ll;
inline ll read() {
ll f = 1, x = 0;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return f * x;
}
const int N = 55;
int a[N][N], n, m, c[N], r[N];
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
// ios::sync_with_stdio(false);
int t = read();
while(t--) {
n = read(), m = read();
memset(c, 0, sizeof c);
memset(r, 0, sizeof r);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) {
a[i][j] = read();
if(a[i][j]) c[i] = 1, r[j] = 1;//r[i]表示这一行是否有1,c[j]表示这一列是否有1,
}
int sum = 0;
for(int i = 1; i <= n; i++) {//枚举行。
if(c[i]) continue;//如果这一行是有1的话,直接跳过,不用考虑了,
for(int j = 1; j <= m; j++) {
if(r[j]) continue;//同上,这一列有1不考虑
else {//否则将这一列标记上1,然后格子数量+1;
sum++;
r[j] = 1;
break;
}
}
}
// cout << sum << endl;
if(sum & 1) puts("Ashish");//判断答案奇偶即可。
else puts("Vivek");
}
return 0;
}
这题全靠瞎猜:分两种情况。
赛后仔细想想好像确实是这样,假设只存在一个1,然后全是0,我们可以通过交换得到任意的排列。
#include
using namespace std;
typedef long long ll;
inline ll read() {
ll f = 1, x = 0;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return f * x;
}
const int N = 510;
int a[N], b[N], n;
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
// ios::sync_with_stdio(false);
int t = read();
while(t--) {
n = read();
int sum0 = 0, sum1 = 0;
for(int i = 1; i <= n; i++) {
a[i] = read();
b[i] = a[i];
}
sort(a + 1, a + 1 + n);
for(int i = 1; i <= n; i++) {
int temp = read();
if(temp) sum1++;
else sum0++;
}
// for(int i = 1; i <= n; i++)
// printf("%d%c", a[i], i == n ? '\n' : ' ');
int flag = 1;
for(int i = 1; i <= n; i++)//判断是否有序,
if(a[i] != b[i]) {
flag = 0;
break;
}
if(flag) puts("Yes");//case 1
else {//case 2
if(sum1 && sum0) puts("Yes");
else puts("No");
}
}
return 0;
}
首先我们明白,左移和右移的操作是等价的,任何通过左移得到的序列,我们都可以通过右移得到,反之亦然。所以我直接统计b序列的每个位置向右移动多少位可以得到在a中的相同位置,最后再统计一圈最大值就行了。
#include
using namespace std;
typedef long long ll;
inline ll read() {
ll f = 1, x = 0;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return f * x;
}
const int N = 2e5 + 10;
int a[N], b[N], sum[N], n;
struct Node {
int value, id;
bool operator < (const Node & t) const {
return value < t.value;
}
}node[N];
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
// ios::sync_with_stdio(false);
n = read();
for(int i = 1; i <= n; i++) {
node[i].value = read();
node[i].id = i;
}
sort(node + 1, node + 1 + n);
for(int i = 1; i <= n; i++) {
a[i] = node[i].value;
b[i] = read();
}
for(int i = 1; i <= n; i++) {
int p = lower_bound(a + 1, a + 1 + n, b[i]) - a;
p = node[p].id;//好像这里直接就可以是p = node[b[i]].id;,写比赛的时候傻了。
// cout << p << endl;
int len = p - i;
if(len < 0) len += n;
sum[len]++;
}
// for(int i = 0; i <= n; i++)
// printf("%d%c", sum[i], i == n ? '\n' : ' ');
int ans = 0;
for(int i = 0; i <= n; i++)
if(sum[i] > sum[ans])
ans = i;
printf("%d\n", sum[ans]);
return 0;
}
我们要保证最优,使所有的好人都可以到达 n , m n, m n,m,所以我们一定要选择在每一个 B B B的边上加墙,这个时候还有一点要注意,如果有好人是紧邻坏人的,那么我们一定不存在一种方案得到答案,这里直接在加墙的时候特判就行了。
加完墙之后,我们要保证所有的好人和 n , m n, m n,m点是联通的,所以我们直接从 n , m n, m n,m点开始 d f s ∣ b f s dfs | bfs dfs∣bfs去访问所有可以达到的点,最后加一个特判,判断是否所有的好人和 n , m n, m n,m是否联通,也就是看visit数组对应的点是否已经标记为1,然后这题就了。
#include
using namespace std;
typedef long long ll;
inline ll read() {
ll f = 1, x = 0;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return f * x;
}
typedef pair<int, int> PII;
const int N = 55;
const int ax[4] = {1, 0, 0, -1}, ay[4] = {0, 1, -1, 0};
char maze[N][N];
int visit[N][N];
int n, m;
struct node{
int x, y;
node(int a = 0, int b = 0) : x(a), y(b) {}
};
queue<node> q;
void bfs(int s,int t) {
while(!q.empty()) q.pop();
visit[s][t] = 1;
q.push(node(s, t));
while(!q.empty()) {
node temp = q.front();
q.pop();
for(int i=0;i<4;i++) {
int tempx = temp.x + ax[i];
int tempy = temp.y + ay[i];
if(maze[tempx][tempy] != '#' && visit[tempx][tempy] == 0) {
visit[tempx][tempy] = 1;
q.push(node(tempx, tempy));
}
}
}
}
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
// ios::sync_with_stdio(false);
int t = read();
while(t--) {
n = read(), m = read();
for(int i = 1; i <= n; i++)
scanf("%s", maze[i] + 1);
for(int i = 0; i <= m + 1; i++)
maze[0][i] = maze[n + 1][i] = '#';
for(int i = 0; i <= n + 1; i++)
maze[i][0] = maze[i][m + 1] = '#';
int flag = 1;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
if(maze[i][j] == 'B') {
// cout << i << " " << j << endl;
int x = i, y = j;
for(int k = 0; k < 4; k++) {
if(maze[x + ax[k]][y + ay[k]] == 'G') {//这个点一定要注意特判,不然直接wa,
flag = 0;
break;
}
if(maze[x + ax[k]][y + ay[k]] == '.')
maze[x + ax[k]][y + ay[k]] = '#';
}
}
if(!flag) break;
}
if(!flag) break;
}
memset(visit, 0, sizeof visit);
if(maze[n][m] != '#') bfs(n, m);
for(int i = 1; i <= n;i++) {
for(int j = 1; j <= m; j++) {
if(maze[i][j] == 'G') {
if(visit[i][j]) continue;
else {
flag=0;
break;
}
}
if(!flag) break;
}
if(!flag) break;
}
if(flag) puts("Yes");
else puts("No");
}
return 0;
}