目录
C - Balanced Bitstring
题意:
给你一个二进制字符串s,里面可能会包含 “?" ;”?“可以修改成0或者1;现在给你一个k,问s的任意长度与为k的子串能否满足以下条件:长度为k的子串中0和1的数量相等,都是;
思路:
首先要发现一个规律 s[i]==s[i+k] , 以为只有这样才能满足上述条件;然后字符串s从位置k开始只要遇见”?“直接跳过,遇见不是”?“的要满足下面条件:若 s[i%k]!="?" ,则 s[i%k]!=s[i] ;如果等于那就不合法;如果 s[i%k]=="?" ,那么 s[i%k]==s[i] ;
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
int t;
cin >>t;
while(t--)
{
int n,k;
cin >>n>>k;
string s;
cin >>s;
int f=1;
for(int i=k-1;i<s.size();i++)
{
if(s[i]=='?') continue;
if(s[i%k]=='?') s[i%k]=s[i];
else if(s[i]!=s[i%k]) {f=0;break;}
}
int x=0,y=0;
for(int i=0;i<k;i++) x+=s[i]=='1'?1:0,y+=s[i]=='0'?1:0;
// cout <<s<<endl;
if(x>k/2||y>k/2) f=0;
puts(f?"YES":"NO");
}
}
D - Tree Tag
题意:
在一棵树上给你A和B的位置,然后分别给出A和B每次能跳跃的最大距离;A先跳跃,问A能否在有限次内追上B;
思路:
A的活动范围为da*2,树的直径为 dmax,dep[B]为A,B之间的距离
- 当da>=dep[B]时,A第一次就能抓到B;
- 当da*2>=db时,B永远不能绕过A跑到另一颗子树上去;
- 当da*2>=dmax时,无论B在哪,A一定能一次抓到B;
今天新学了树形DP求树的直径,还挺好用的~
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+7;
int h[N],e[N<<1],ne[N<<1],w[N<<1],idx;
int d[2][N],dmax,dep[N];//d[0][u]表示u到其子树中叶子节点的最长距离,d[1][u]表示次长
void add(int a,int b,int c)
{
e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}
void dfs(int u,int fa)
{
for(int i=h[u];~i;i=ne[i])
{
int j=e[i];
if(j==fa) continue;
dep[j]=dep[u]+1;
dfs(j,u);
if(d[0][u]<d[0][j]+w[i]) d[1][u]=d[0][u],d[0][u]=d[0][j]+w[i];
else if(d[1][u]<d[0][j]+w[i]) d[1][u]=d[0][j]+w[i];
dmax=max(dmax,d[0][u]+d[1][u]);
}
}
int main()
{
int t;cin >>t;
while(t--)
{
memset(h,-1,sizeof h);
memset(d,0,sizeof d);
dmax=idx=0;
int n,a,b,da,db;
cin >>n>>a>>b>>da>>db;
for(int i=0;i<n-1;i++)
{
int u,v;cin >>u>>v;
add(u,v,1),add(v,u,1);
}
dep[a]=0;
dfs(a,-1);
puts((da*2>=min(dmax,db)||da>=dep[b])?"Alice":"Bob");
}
}