目录
题目传送门
题意与任务和结果
看完题目后,我们了解到了其实题目就是一个模拟的题目,无疑就是模拟Bessie在数轴上的行动,模拟的答案是Bessie在数轴上击破的炮击目标,只是每个数轴上的整数点上都有一个需要处理的子任务。根据题意,子任务大致有两种:
- 是这个点上的是一个炮击目标(也就是q=1)
- 是这个点上的是一个跳板(也就是q=0)
在细分该子任务的其他子任务,那么每一个点上都有一个结果:
- 这个点上是炮击目标,且未被炮击过且k(能量)
v时,炮击目标+1
- 这个点上是炮击目标,且未被炮击过且k(能量)
v时,炮击目标+0
- 这个点上是炮击目标,且被炮击过时,炮击目标+0
- 这个点上是跳板时,跳转方向翻转(如向右变向左),k值发生变化,k=k+v
还需要考虑什么时候结束:
- 弹跳无限长的时间或直到她离开数轴时结束
75分的代码
那么这些我们都列举出来了,模拟这个过程也就轻而易举了。
模拟代码如下:
#include<bits/stdc++.h>
using namespace std;
long long n,s,p,q[100005],v[100005],ans,k=1;
bool flag,m[100005];
int main()
{
cin>>n>>s;
p=s;
for(int i=1;i<=n;i++)
{
cin>>q[i]>>v[i];
}
if(q[p]==1)
{
if(k>=v[p]&&m[p]==0)
{
ans++;
m[p]=1;
}
}
else
{
k+=v[p];
flag=1;
}
while(p>=1&&p<=n)
{
if(flag==0)
{
p+=k;
if(q[p]==1)
{
if(k>=v[p]&&m[p]==0)
{
ans++;
m[p]=1;
}
}
else
{
k+=v[p];
if(flag==1)
{
flag=0;
}
else
{
flag=1;
}
}
}
else
{
p-=k;
if(q[p]==1)
{
if(k>=v[p]&&m[p]==0)
{
ans++;
m[p]=1;
}
}
else
{
k+=v[p];
if(flag==1)
{
flag=0;
}
else
{
flag=1;
}
}
}
//cout<<p<<endl;
}
cout<<ans;
return 0;
}
75分代码分析
我们用两个整形数组分别储存v和q,然后再用一个bool的数组储存该炮击目标是否被炮击过,再用一个bool的变量判断向左还是向右(0向右,1向左),那么程序的模拟范围就在[1,n]中,再根据上述我们列出的的子任务和结果进行模拟,那么结果就非常轻松地出来了。
但......
上述代码结果如下
只有75分......
我们发现T了5个点。
该怎么办呢?我们不妨猜一下当Bessie在数轴上的两个跳板之间来回跳跃,那是不是就死循环了。题目中有一句话:
- 如果 Bessie 弹跳无限长的时间或直到她离开数轴,她会击破多少个炮击目标?
也就是说但Bessie 弹跳无限长的时间或直到她离开数轴时,这个模拟程序就结束。我们好像并没有考虑到要判断是否弹跳无限长时间。所以T了。
那我们只需要加一个变量t,放在while的开头,每次都+1,如果Bessie跳到了炮击目标上,就将t给清零,因为并没有在反复跳,当tn时,也就意味着我已经弹跳了超过n次且没有到过炮击目标,也就是跳跃时间无限长的情况,我们满足这个情况跳出这个模拟程序即可。
修改后程序的模拟部分代码
那么模拟程序也就会变成下面这个程序:
while(p>=1&&p<=n)
{
r++;
if(r==n)
{
break;
}
if(flag==0)
{
p+=k;
if(q[p]==1)
{
if(k>=v[p]&&m[p]==0)
{
ans++;
m[p]=1;
r=0;
}
}
else
{
k+=v[p];
if(flag==1)
{
flag=0;
}
else
{
flag=1;
}
}
}
else
{
p-=k;
if(q[p]==1)
{
if(k>=v[p]&&m[p]==0)
{
ans++;
m[p]=1;
r=0;
}
}
else
{
k+=v[p];
if(flag==1)
{
flag=0;
}
else
{
flag=1;
}
}
}
//cout<<p<<endl;
}
这样这个问题就结束了。
AC代码
附上AC代码
#include<bits/stdc++.h>
using namespace std;
long long n,s,p,q[100005],v[100005],ans,k=1,r;
bool flag,m[100005];
int main()
{
cin>>n>>s;
p=s;
for(int i=1;i<=n;i++)
{
cin>>q[i]>>v[i];
}
if(q[p]==1)
{
if(k>=v[p]&&m[p]==0)
{
ans++;
m[p]=1;
}
}
else
{
k+=v[p];
flag=1;
}
while(p>=1&&p<=n)
{
r++;
if(r==n)
{
break;
}
if(flag==0)
{
p+=k;
if(q[p]==1)
{
if(k>=v[p]&&m[p]==0)
{
ans++;
m[p]=1;
r=0;
}
}
else
{
k+=v[p];
if(flag==1)
{
flag=0;
}
else
{
flag=1;
}
}
}
else
{
p-=k;
if(q[p]==1)
{
if(k>=v[p]&&m[p]==0)
{
ans++;
m[p]=1;
r=0;
}
}
else
{
k+=v[p];
if(flag==1)
{
flag=0;
}
else
{
flag=1;
}
}
}
//cout<<p<<endl;
}
cout<<ans;
return 0;
}
完结,感谢阅读。