题意:有一个n*m的字符,‘#'代表黑色,’.'代表白色,每次能使得黑色上下左右的白色变黑,求最少操作次数可以将他全部变黑。
思路:以每个黑色点做最短路,再bfs。
#include<bits/stdc++.h>
using namespace std;
char s[1005][1005];
int d[1005][1005];
int x[1000005],y[1000005];
int h,w;
int dx[4]={0,0,-1,1};
int dy[4]={1,-1,0,0};
int main(){
scanf("%d%d",&h,&w);
getchar();
int t=0;
for(int i=1;i<=h;i++){
for(int j=1;j<=w;j++){
scanf("%c",&s[i][j]);
if(s[i][j]=='.')
d[i][j]=1e9;
else{
d[i][j]=0;
x[t]=i;
y[t++]=j;
}
}
getchar();
}
int s=0,ans=0;
while(s<t){
int xx=x[s],yy=y[s++];
for(int i=0;i<4;i++){
int u=xx+dx[i];
int v=yy+dy[i];
if(u<1||u>h||v<1||v>w||d[u][v]<=d[xx][yy]+1)
continue;
d[u][v]=d[xx][yy]+1;
ans=max(ans,d[u][v]);
x[t]=u;
y[t++]=v;
}
}
printf("%d\n",ans);
}
题意:给定棋盘,两个人移动棋子,每个人有n种操作,最后如果棋子还在盘子里,则输出YES,否则输出NO。
思路:从后往前推,如果中途区间非法,则失败,如果最后棋子开始的位置不在推出的区间内,则失败。
#include<bits/stdc++.h>
using namespace std;
char s[200005],t[200005];
int h,w,n,sr,sc;
int walk1(){
int l=1,r=h;
for(int i=n;i>=1;i--){
if(t[i]=='U')
r=min(h,r+1);
else if(t[i]=='D')
l=max(l-1,1);
if(s[i]=='U')
l++;
else if(s[i]=='D')
r--;
if(l>r)
return 1;
}
return (sr<l||sr>r);
}
int walk2(){
int l=1,r=w;
for(int i=n;i>=1;i--){
if(t[i]=='L')
r=min(w,r+1);
else if(t[i]=='R')
l=max(l-1,1);
if(s[i]=='R')
r--;
else if(s[i]=='L')
l++;
if(l>r)
return 1;
}
return (sc<l||sc>r);
}
int main(){
scanf("%d%d%d",&h,&w,&n);
scanf("%d%d",&sr,&sc);
scanf("%s",s+1);
scanf("%s",t+1);
if(walk1()||walk2())
puts("NO");
else puts("YES");
}
题意:有一棵树,每个节点都有一枚硬币,两个人轮流操作,每次可以选则一个节点删除里面的所有硬币,如果该节点硬币为0,则与他相邻的所有节点的硬币都转移到该节点上,如果最后谁无法操作,则谁输,另一个人赢。
思路:每次操作的结果要么是删除所有叶子节点,要么保留一个叶子节点,删除其他点。。。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
int n,f[maxn],dep[maxn];
vector<int>g[maxn];
void dfs(int u,int fa){
for(int i=0;i<g[u].size();i++)
if(g[u][i]!=fa)
dep[g[u][i]]=dep[u]+1,dfs(g[u][i],u);
}
int main(){
f[0]=1;
f[1]=0;
scanf("%d",&n);
for(int i=2;i<=n;i++)
if(f[i-1]&&f[i-2])
f[i]=0;
else f[i]=1;
int x,y;
for(int i=2;i<=n;i++){
scanf("%d%d",&x,&y);
g[x].push_back(y);
g[y].push_back(x);
}
dfs(1,0);
int t=1;
for(int i=2;i<=n;i++)
if(dep[i]>dep[t])
t=i;
for(int i=1;i<=n;i++)
dep[i]=0;
dfs(t,0);
t=0;
for(int i=1;i<=n;i++)
t=max(t,dep[i]);
if(f[t])
puts("First");
else puts("Second");
}