F - New Year’s Puzzle
题目链接
题解
首先很明显的是初始黑格子为奇数个的时候答案为No。我们将黑格子按照坐标排序(优先考虑左边的黑格子),我们发现当放了奇数个黑格子之后,右边能放的2*1的长方形都是确定的,因此下一个黑格子也是能确定其坐标。我们还要保证奇数个黑格子不与其前一个在同一列。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
struct node {
int x,y;
bool operator <(const node& d )const{
if(x==d.x)
return y<d.y;
return x<d.x;
}
}a[maxn];
void solve(){
int n,m;
scanf("\n%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&a[i].y,&a[i].x);
}
if(m&1){
puts("No");
return ;
}
sort(a+1,a+1+m);
for(int i=2;i<=m;i++){
if(i%2==0){
int tmp=(a[i].x-a[i-1].x)%2,tmp2=abs(a[i].y-a[i-1].y);
if(tmp==tmp2){
puts("No");
return ;
}
}
else {
if(a[i].x==a[i-1].x) {
puts("No");
return ;
}
}
}
puts("Yes");
}
int main(){
int T;scanf("%d",&T);while(T--)
solve();
return 0;
}
G - Moving to the Capital
题目链接
题解
先bfs求出
1
1
1号点到其他点的最短距离,按照
d
i
d_i
di顺序依次更新答案即可。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
vector<int> vi[maxn];
int dis[maxn];
int ans[maxn];
bool vis[maxn];
stack<int> st;
void bfs(){
dis[1]=0;
queue<int> q;
q.push(1);
while(!q.empty()){
int u=q.front();q.pop();
st.push(u);
for(auto v:vi[u]){
if(dis[v]>dis[u]+1){
dis[v]=dis[u]+1;
q.push(v);
}
}
}
}
void dfs(int u){
ans[u]=dis[u];
vis[u]=true;
for(auto v:vi[u]){
if(!vis[v])
dfs(v);
if(dis[v]<=dis[u]){
ans[u]=min(ans[u],dis[v]); //用掉这次机会
}
else{
ans[u]=min(ans[u],ans[v]);
}
}
}
// char s[maxn];
void solve(){
int n,m;
scanf("\n%d%d",&n,&m);
for(int i=1;i<=n;i++){
dis[i]=1e9;
vi[i].clear();
vis[i]=false;
ans[i]=1e9;
}
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
vi[u].push_back(v);
}
bfs();
// dfs(1);
for(int i=1;i<=n;i++){
ans[i]=dis[i];
}
while(!st.empty()){
int u=st.top();
st.pop();
for(auto v:vi[u]){
if(dis[v]>dis[u])
ans[u]=min(ans[u],ans[v]);
else ans[u]=min(ans[u],dis[v]);
}
}
for(int i=1;i<=n;i++){
printf("%d ",ans[i]);
}
puts("");
}
int main(){
// freopen("in.txt","r",stdin);
int T;scanf("%d",&T);while(T--)
solve();
return 0;
}