[Code+#7]蚂蚁
\(\mathsf{Title\space Describe.}\)
在东西排布的两棵树之间悬挂着一条长为 \(L\) 的细绳,有 \(N\) 只蚂蚁在这条绳上。这些蚂蚁希望通过绳子爬到任何一棵树上,但这条绳太细了,导致两只蚂蚁不能并排爬行,也不能交错而过。
它们想到了一个方法:每只蚂蚁都以每单位时间移动一个单位距离的速度不断向前爬,当迎面碰到另一只蚂蚁时,两只蚂蚁都将立即掉头并继续向前爬。现在,蚂蚁们想知道自己是否能爬下绳子,如果能,它们还希望知道自己爬下绳子所花的时间。为了方便,我们按初始时位置从东到西的顺序对蚂蚁从 \(1\) 开始编号。
\(\mathsf{Analytical\space thinking.}\)
遇到这种模拟题,千万不能具体地去处理对待,一定要从总体去看待题目。
比方说这道题,我最初的思路是一只只的蚂蚁地去处理每只蚂蚁,想了个 \(O(n^2)\) 的思路,但是 \(1\le n\le10^5\),显然不能在 \(1\) 秒内通过。
然后我就想啊:
先考虑极端情况:有 \(10^5\) 只蚂蚁,这么多蚂蚁,如果一只只去看是在是不科学,如果一只蚂蚁朝向东边,那么直接让它走过去好了——但是如果在它的东边还有蚂蚁怎么办呢?哦,对了,如果遇到的话,那么可以看成是穿过去了(双双掉头就相当于传过去),那就先让朝向东边的蚂蚁走过去,然后我再让这些朝西边的蚂蚁往左边走不就好了?
\(\mathsf{Code.}\)
//2021/8/23
#include <iostream>
#include <cstdio>
#define debug(c) cerr<<#c<<" = "<<c<<endl
namespace Newstd
{
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9')
{
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9')
{
x=x*10+ch-'0';ch=getchar();
}
return x*f;
}
inline void print(int x)
{
if(x<0)
{
putchar('-');x=-x;
}
if(x>9)
{
print(x/10);
}
putchar(x%10+'0');
}
}
using namespace Newstd;
using namespace std;
const int ma=100005;
int a[ma],st[ma];
int n,l;
int main(void)
{
scanf("%d%d",&n,&l);
for(register int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(register int i=1;i<=n;i++)
{
scanf("%d",&st[i]);
}
for(register int i=1;i<=n;i++)
{
if(st[i]==false)
{
printf("%d ",a[i]);
}
}
//这里要保证面向东边的蚂蚁首先到达,所以分成两个循环
for(register int i=1;i<=n;i++)
{
if(st[i]==true)
{
printf("%d ",l-a[i]);
}
}
return 0;
}

浙公网安备 33010602011771号