Codeforces Round #765 (Div. 2) A~C题解
A. Not Shading
题意
每次操作可选择一个黑色格子将该行全染为黑色或该列染为黑色,求最少需要多少次操作使(r,c)位置为黑色,若无法得到输出-1。
做法
若(r,c)初始就是黑色,则操作0次
若r行或c列存在黑色格子,则操作1次
若存在黑色格子,则操作2次
若不存在黑色格子,则无解输出-1
#include<bits/stdc++.h>
using namespace std;
int n,m;
char a[109][109];
int main()
{
int i,j,k,t,r,c;
cin>>t;
while(t--){
int flag=0,flag1=0;
scanf("%d%d%d%d",&n,&m,&r,&c);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
cin>>a[i][j];
if((i==r||j==c)&&a[i][j]=='B')flag=1;
if(a[i][j]=='B')flag1=1;
}
if(a[r][c]=='B')printf("0\n");
else if(flag)printf("1\n");
else if(flag1)printf("2\n");
else printf("-1\n");
}
return 0;
}
B. Not Sitting
题意
有n行m列座位,Tina选择k(0<=k<=nm-1)桶油漆进行染色,Rahul选择一个没有染色的座位后Tina选择一个座位,Tina想Rahul远一些,Rahul想离Tina近一些,他们每次的选择都是最明智的,求k等于0到nm-1时他们之间的距离
做法
由于Rahul想离Tina近一些,他最佳选择为中间的位置,当他选择四个顶点的位置时两人之间的距离一定最大,为n-1+m-1.所以用bfs从四个顶点向中心蔓延,记录每个点的距离,从小到大排序后输出
#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[500009],mv[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
void bfs(int x,int y,int len){
queue<pair<int,int> >p;
pair<int,int> no,le;
map<pair<int,int>,int>has;
p.push({1,1});
has[{1,1}]=len;
p.push({1,y});
has[{1,y}]=len;
p.push({x,1});
has[{x,1}]=len;
p.push({x,y});
has[{x,y}]=len;
a[1]=len;
a[y]=len;
a[(x-1)*y+1]=len;
a[x*y]=len;
while(!p.empty()){
no=p.front();
p.pop();
for(int i=0;i<4;i++){
le.first=no.first+mv[i][0];
le.second=no.second+mv[i][1];
if(le.first>0&&le.first<=n&&le.second>0&&le.second<=m&&!has[le])
{
has[le]=has[no]-1;
a[(le.first-1)*y+le.second]=has[le];
p.push(le);
}
}
}
sort(a+1,a+x*y+1);
for(int i=1;i<=x*y;i++)
printf("%d ",a[i]);
printf("\n");
}
int main()
{
int i,j,k,t,r,c,x,y,z;
cin>>t;
while(t--){
scanf("%d%d",&n,&m);
bfs(n,m,n-1+m-1);
}
return 0;
}
C. Not Assigning
题意
给一颗大小为n的树,对所有边进行赋值,使每条边的权值为质数并且任意两条相邻边的权值之和也是质数
做法
由于除2以外任意两个质数的和都为偶数,所有要使任意两条相邻边的权值之和为质数,要有一边权值为2,并且每个点度数小于3(若某个点度数大于等于3,必然存在复数个权值为2或奇数的边).所以该树若满足条件必然为链状(每个点的度数小于等于2),使用dfs从链头遍历每条边按2和任意一个非2质数交替赋值,最后按输入顺序输出每条边的权值(输入时用map记录每条边的输入顺序)。
#include <bits/stdc++.h>
using namespace std;
int idx,e[200009],h[200009],ne[200009],r[200009],ans[200009],n;
map<pair<int,int>,int>has;
void add(int x,int y){
e[idx]=y;
ne[idx]=h[x];
h[x]=idx++;
}
void dfs(int x,int flag,int val){
for(int i=h[x];i!=-1;i=ne[i]){
if(e[i]!=flag){
ans[has[{x,e[i]}]]=val;
dfs(e[i],x,5-val);
}
}
}
int main()
{
int t,i,j,m,k,x,y,star;
cin>>t;
while(t--){
memset(r,0,sizeof r);
memset(h,-1,sizeof h);
scanf("%d",&n);
for(i=1;i<=n-1;i++){
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
r[x]++;
r[y]++;
has[{x,y}]=i;
has[{y,x}]=i;
}
for(i=1;i<=n;i++)
if(r[i]>=3)break;
if(i<=n){
printf("-1\n");
continue;
}
star=0;
for(i=1;i<=n;i++)
if(r[i]==1){
star=i;
break;
}
dfs(star,0,2);
for(i=1;i<n;i++)
printf("%d ",ans[i]);
printf("\n");
}
return 0;
}