A. Three Doors
思路:判断当前门后和当前门后的钥匙所对应的门都是否有钥匙即可.
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N =5e5+10,mod=998244353;
void solve()
{
int n,a[4];
cin>>n;
cin>>a[1]>>a[2]>>a[3];
if(a[n]==0)
{
cout<<"NO\n";
return ;
}
if(a[a[n]]==0)
{
cout<<"NO\n";
return ;
}
cout<<"YES\n";
return ;
}
signed main()
{
int t;
cin>>t;
while(t--)
solve();
return 0;
}
B. Also Try Minecraft
思路:前后跑两次,分别判断是否会产生贡献,求前缀和即可(正反书序不同贡献不同)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N =5e5+10,mod=998244353;
int shun[100005],ni[100005];
int h[100005];
void solve()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>h[i];
if(i!=1)
if(h[i]<h[i-1])
shun[i]=shun[i-1]+(h[i-1]-h[i]);
else
shun[i]=shun[i-1];
}
for(int i=n;i>=1;i--)
if(i!=n)
if(h[i]<h[i+1])
ni[i]=ni[i+1]+(h[i]-h[i+1]);
else
ni[i]=ni[i+1];
int l,r;
while(m--)
{
cin>>l>>r;
if(l<=r)
{
cout<<shun[r]-shun[l]<<"\n";
}
else
{
cout<<ni[l]-ni[r]<<"\n";
}
}
return ;
}
signed main()
{
solve();
return 0;
}
C. Recover an RBS
思路:首先判断是否存在的左右括号等于n/2个(n为字符串长度),若等于那么问号的括号方向也就确定了.
然后针对于这个序列,谈心的去想,我们想要尽量小的影响产生在串上面,所以,我们先将左右括号贪心的分配在问号的位置,尽量先把左括号分配完在插入右括号.此时在按照贪心的思想,我们要满足RBS的定义,那么在遍历字符串的时候,左括号的数量在每个位置都要大于等于右括号的数量,为了最小程度的找出第二种括号排列序列,我们就需要把最左边的由问号变成的')'和最右边的由问号变成的'('进行位置交换,这样交换后两者对于RBS组成的影响是最小的.在按照上面的规则,直接遍历记录左右括号的数量.当右括号大于左括号的数量的时候就说明不合适,就连对于原序列贪心的最小影响的情矿都不合法,就表明只有一种排列方法.
#include<bits/stdc++.h>
using namespace std;
void solve()
{
string s;
cin>>s;
int zuo=0,you=0,wen=0;
for(int i=0;i<s.size();i++)
{
if(s[i]=='(')
zuo++;
else if(s[i]==')')
you++;
else if(s[i]=='?')
wen++;
}
if(zuo==s.size()/2||you==s.size()/2)
{
cout<<"YES\n";
return ;
}
int l=1e8,r=-1;
for(int i=0;i<s.size();i++)
{
if(s[i]=='?')
if(zuo<s.size()/2)
{
s[i]='(';
r=max(r,i);
zuo++;
}
else
{
s[i]=')';
l=min(l,i);
}
}
swap(s[l],s[r]);
zuo=0;
for(int i=0;i<s.size();i++)
{
if(s[i]=='(')
zuo++;
else if(s[i]==')')
zuo--;
if(zuo<0)
{
cout<<"YES\n";
return ;
}
}
cout<<"NO\n";
return ;
}
signed main()
{
int t;
cin>>t;
while(t--)
solve();
return 0;
}
D. Rorororobot
思路:我们首先要判断横纵坐标之差是不是k的倍数,如果不是就表明肯定走不到.注意,我们不需要最少的步数,所以我们就可以走一种策略,从当前点走到能走到的最上方,再向右走到目的地的上方,在向下走到目的点,这样是最贪心的走法,如果连这个都走不到,那么也就没办法走到了.然后这个方法要求我们预处理出区间最大值,当我们能向上走到得到最大值大于区间内最大的障碍物的高度时,就一定可以走到.
那么线段树(亲测不会t)和st表都可以.
#include<bits/stdc++.h>
using namespace std;
struct node
{
int l,r,minn;
}tr[4*200010];
int a[200010];
void build(int l,int r,int node)
{
tr[node].l=l;
tr[node].r=r;
if(l==r)
{
tr[node].minn=a[l];
return ;
}
int mid=(l+r)>>1;
build(l,mid,node<<1);
build(mid+1,r,node<<1|1);
tr[node].minn=max(tr[node<<1].minn,tr[node<<1|1].minn);
return ;
}
int query(int l,int r,int node)
{
if(l<=tr[node].l&&tr[node].r<=r)
return tr[node].minn;
int mid=(tr[node].l+tr[node].r)>>1;
int minn=-1;
if(l<=mid)
minn=max(query(l,r,node<<1),minn);
if(r>mid)
minn=max(query(l,r,node<<1|1),minn);
return minn;
}
void solve()
{
int n,m,q;
cin>>n>>m;
for(int i=1;i<=m;i++)
cin>>a[i];
build(1,m,1);
cin>>q;
while(q--)
{
int sx,sy,ex,ey,k;
cin>>sx>>sy>>ex>>ey>>k;
if(abs(sx-ex)%k||abs(sy-ey)%k)
{
cout<<"NO\n";
continue;
}
int maxx=max(ex,sx);
maxx=(n-maxx)/k*k+maxx;
if(maxx>query(min(sy,ey),max(sy,ey),1))
{
cout<<"YES\n";
}
else
{
cout<<"NO\n";
}
}
return ;
}
signed main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
solve();
return 0;
}