题目:
在2312年,宇宙中发现了n台巨型对撞机,这些对撞机分别用1-n的自然数标识。科学家们不知道启动这些对撞机会发生什么危险事故,所以这些机器,刚开始都是处于关闭状态。
随着科学家们的研究发现,第i台对撞机启动是安全的,如果其他已经启动的对撞机的标识数都跟这台对撞机标志数互质。(例如假设前面启动的是j,如果i能启动,那么(I,j)互为质数,也就是(I,j)的最大公约数为1)!如果两台对撞机不互为质数就启动,那么就会发生爆炸事故。
基于前面的研究,科学家们准备做各种启动和关闭对撞机的实验,为了确保科学家的生命安全。你要设计一个远程遥控的软件。刚开始,所有的对撞机都是关闭状态。你的程序将会收到许多询问,格式为“启动/关闭第i台对撞机”。这程序应该能处理这些询问(根据收到询问的先后顺序处理)。这程序应该按照如下的格式输出处理结果。
如果询问是”+ i”(表示第i台对撞机启动),这程序应该按照下面三种的情况之一输出结果。
(1)“Success”,如果启动第i台是安全的
(2)“Already on”,如果第i在这个询问之前就已经启动了。
(3)“Conflict with j”,如果第i台跟前面启动了的第j台冲突,就不能启动第I,如果前面有多台跟i冲突,那么只要输出其中任何一台就可以。
如果询问是”-i”(表示关闭第i台对撞机),这程序应该按照下面两种的情况之一输出结果。
(1)“Success”,表示关闭第i台对撞机
( 2 )“ Already off ”,表示第 i 台对撞机在询问之前就已经关闭了。
分析:
一开始真的用GCD做了,结果不用想超时,后来听别人说是两个数互为质数则一定不会冲突,或者一个是质数,另一个不是上个数的倍数则两数互质。两数如果有相同质数,就冲突。具体实现可以用桶排,因为N才十万。
附上代码:
const
maxn=100000;
var
status,data,ooc:array [0..maxn] of longint;
prime:array [0..maxn] of boolean;
n,m:longint;
procedure main;
var
i,j,k,temp,test,v:longint;
s:shortstring;
flag:boolean;
begin
fillchar(prime,sizeof(prime),true);
for i:=2 to trunc(sqrt(maxn)) do
if prime[i] then
for j:=2 to trunc(sqrt(maxn)) div i do
prime[i*j]:=false;
fillchar(status,sizeof(status),0);
readln(n,m);
for i:=1 to m do
begin
readln(s);
val(copy(s,3,length(s)-1),temp);
if s[1]='+' then
begin
if status[temp]>0 then
writeln('Already on')
else
begin
if prime[temp] then
begin
if ooc[temp]=0 then
begin
v:=1;
data[v]:=temp;
flag:=true;
k:=temp;
end
else
begin
flag:=false;
test:=temp;
end;
end
else
begin
v:=0;
k:=temp;
j:=2;
flag:=true;
while temp<>1 do
begin
if temp mod j=0 then
begin
if ooc[j]>0 then
begin
flag:=false;
test:=j;
break;
end;
inc(v);
data[v]:=j;
while temp mod j=0 do
temp:=temp div j;
end;
inc(j);
end;
end;
if flag then
begin
for j:=1 to v do
inc(ooc[data[j]]);
status[k]:=k;
writeln('Success');
end
else
begin
j:=0;
while j<=n do
begin
inc(j,test);
if status[j]>0 then
begin
writeln('Conflict with ',j);
break;
end;
end;
end;
end;
end
else
begin
if status[temp]=0 then
writeln('Already off')
else
begin
if prime[temp] then
begin
status[temp]:=0;
dec(ooc[temp]);
writeln('Success');
end
else
begin
status[temp]:=0;
j:=2;
while temp<>1 do
begin
if temp mod j=0 then
begin
dec(ooc[j]);
while temp mod j=0 do
temp:=temp div j;
end;
inc(j);
end;
writeln('Success');
end;
end;
end;
end;
end;
begin
main;
end.