好像不少人(包括我) 一开始都看错题意了…
It is “share a row or column” not “share sides”.
解法: 暴力即可
Code:
int a[MX][MX];
bool r[MX],c[MX];
int n,m;
bool sol(){
for(int i = 1;i <= n;++i){
for(int j = 1;j <= m;++j){
if(!r[i] && !c[j]) {
r[i] = c[j] = true;return true;
}
}
}return false;
}
int main(){
int T;scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
clr(r,false);clr(c,false);
for(int i = 1;i <= n;++i){
for(int j = 1;j <= m;++j){
scanf("%d",&a[i][j]);
if(a[i][j]) r[i] = c[j] = true;
}
}
int res = 0;
while(true){
if(sol()){res++;}
else break;
}
if(res % 2 == 1) printf("Ashish\n");
else printf("Vivek\n");
}
return 0;
}
解法: 容易发现只要不是只有Type 0 或 Type 1 就一定可以排好序,当然如果原本有序也可
Code:
int a[MX];
int b[MX];
int main(){
int T;scanf("%d",&T);
while(T--){int n;
int cnt1 = 0,cnt2 = 0;
scanf("%d",&n);
for(int i = 1;i <= n;++i) scanf("%d",&a[i]);
for(int i = 1;i <= n;++i) {scanf("%d",&b[i]);if(b[i]) cnt1++;else cnt2++;}
if(cnt1 == 0 || cnt2 == 0){
bool flag = true;
for(int i = 2;i <= n;++i){
if(a[i] < a[i-1]) {flag = false;break;}
}
if(flag) printf("Yes\n"); else printf("No\n");
} else printf("Yes\n");
}
return 0;
}
解法:
注意到:
1.没必要a和b都操作,只需要操作其中一个就行
2.可以只向某个方向偏移一次,偏移量为 [ 1 , n ] [1, n] [1,n]
因为是n的排列,所以可以先记录下1 ~ n 每个值若要与另一个序列中的它匹配,所需要向左/右 的偏移量x,同时记录向左/右偏移量为 x 时所能匹配上的元素个数。
最后枚举向左/右的偏移量,找到在当前偏移量下的最大贡献即可。
Code:
int a[MX],posa[MX];
int b[MX],posb[MX];
int d1[MX],d2[MX];
int num1[MX],num2[MX];
int main(){
int n;scanf("%d",&n);
for(int i = 1;i <= n;++i){
scanf("%d",&a[i]);
posa[a[i]] = i;
}
for(int i = 1;i <= n;++i){
scanf("%d",&b[i]);
posb[b[i]] = i;
}
for(int i = 1;i <= n;++i){
int p1 = posa[i],p2 = posb[i];
if(p2 >= p1){
d1[i] = p2 - p1;
d2[i] = p1 + (n - p2);
} else{
d1[i] = (n-p1) + p2;
d2[i] = p1 - p2;
}
num1[d1[i]]++;
num2[d2[i]]++;
}
int res = 0;
for(int i = 1;i <= n;++i){
res = max(res,num1[i]);
res = max(res,num2[i]);
}
printf("%d\n", res);
return 0;
}
解法:
显然如果一开始所有好人都无法逃脱,则输出No
否则,只需要把所有坏人的周围的空位置堵住即可
粗略证明:
如果一种可行策略中,某个坏人周围 (四个方向相邻的位置) 有未被堵住的位置 ( i , j ) (i,j) (i,j),则从 ( i , j ) (i,j) (i,j) 一定无法逃脱
首先此处一定不会是好人(否则好人也无法逃脱,就不是可行策略了);
那么在此基础上再堵住此处,对可行性没有影响
都堵上之后,每个坏人也自然都无法逃脱
如果堵住了某个坏人的周围,使得某个好人也无法逃脱,则说明无论如何都无法符合条件
(说明某个好人要逃脱必须经过某个坏人的周围,要使得该好人逃脱必须同时让该坏人也能逃脱)
最后在判断是否符合条件即可
Code:
int n,m;
char mp[MX][MX];
struct node{
int x,y;
};
int tox[] = {1,-1,0,0};
int toy[] = {0,0,-1,1};
bool judge(int x,int y){
if(x < 1 || y < 1 || x > n || y > m) return false;
if(mp[x][y] == '#') return false;
return true;
}
bool check(){
bool vis[MX][MX];clr(vis,false);
queue<node>q;
while(!q.empty()) q.pop();
if(mp[n][m] != '#') {q.push((node){n,m});vis[n][m] = true;}
while(!q.empty()){
node now = q.front();q.pop();
for(int i = 0;i < 4;++i){
int nx = now.x + tox[i];
int ny = now.y + toy[i];
if(vis[nx][ny]) continue;
if(judge(nx,ny)){
vis[nx][ny] = true;
q.push((node){nx,ny});
}
}
}
for(int i = 1;i <= n;++i){
for(int j = 1;j <= m;++j){
if(mp[i][j] == 'G' && vis[i][j] == false) return false;
}
}
//debug1("True");
return true;
}
bool check2(){
bool vis[MX][MX];clr(vis,false);
queue<node>q;
while(!q.empty()) q.pop();
if(mp[n][m] != '#') {q.push((node){n,m});vis[n][m] = true;}
while(!q.empty()){
node now = q.front();q.pop();
for(int i = 0;i < 4;++i){
int nx = now.x + tox[i];
int ny = now.y + toy[i];
if(vis[nx][ny]) continue;
if(judge(nx,ny)){
vis[nx][ny] = true;
q.push((node){nx,ny});
}
}
}
for(int i = 1;i <= n;++i){
for(int j = 1;j <= m;++j){
if(mp[i][j] == 'B' && vis[i][j] == true) return false;
}
}
return true;
}
bool solve(){
if(!check()) return false;
for(int i = 1;i <= n;++i){
for(int j = 1;j <= m;++j){
if(mp[i][j] == 'B'){
if(j != 1 && mp[i][j-1] == '.') mp[i][j-1] = '#';
if(j != m && mp[i][j+1] == '.') mp[i][j+1] = '#';
if(i != 1 && mp[i-1][j] == '.') mp[i-1][j] = '#';
if(i != n && mp[i+1][j] == '.') mp[i+1][j] = '#';
}
}
}
if(check() && check2()) return true;
else return false;
}
void init(){
for(int i = 1;i <= n;++i){
for(int j = 1;j <= m;++j){
mp[i][j] = 0;
}
}
}
int main(){
int T;scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&m);init();
for(int i = 1;i <= n;++i){
scanf("%s",mp[i]+1);
}
if(solve()) printf("Yes\n"); else printf("No\n");
}
return 0;
}
题解:
因为题目中说
at least max(1,k−2) elements of the subsequence have the i-th bit set in their binary representation
所以对于任何长度小于等于3的子序列,它的贡献为每个元素之间按位或
而任何长度大于3的子序列,其贡献不会大于它之中某个长度小于等于3的子序列
所以我们只需要取最多长度为3的子序列即可
Code:
ll a[MX];
int main(){
int n;cin >> n;
ll res = 0;
for(int i = 1;i <= n;++i) cin >> a[i];
for(int i = 1;i <= n;++i){
for(int j = i;j <= n;++j){
for(int k = j;k <= n;++k){
res = max(res,a[i] | a[j] | a[k]);
}
}
}
cout << res << endl;
return 0;
}