zhuceyongde 发表于 2008-11-18 23:29:45

关于直线扫描格子问题

有一个n*m(1 <=n,m <=10^6)的格子,在每个格子的中心都有一个人,A在最左下角的格子中,他手中有一把威力很大的枪,一枪可以击中直线上的任何目标,A只能在左下角的格子中,但可以转方向,求其最少开几枪可以将其余n*m-1人打中。

我想了好长时间,感觉与欧拉函数有关,但不知怎么做,
谁有思路,帮下忙。

无心人 发表于 2008-11-19 08:25:36

很暴力

gxqcn 发表于 2008-11-19 08:29:31

还没细想。

假定开枪者枪口指向正上方,
则每次顺时针旋转一个最小的角度,
直到此时该枪口上有人存活则扣动扳机。
似乎所费的子弹已足够少了。:lol :Q:

换一种策略(也许并不好):
首先应瞄准矩形最外围尚存活的那些人,
由于枪的威力巨大,子弹会顺带干掉矩形内部处在射线上的家伙。
当外围敌人消灭后,矩形就相对瘦了一圈,
继续沿该策略执行下去,就可完成任务。

sunwukong 发表于 2008-11-19 08:34:36

此问题与以下问题等价:

$1 <= x <= n$

$1 <= y <= m$

$x$,$y$ 互素

求 $(x,y)$ 的个数

由欧拉函数的定义:

如果 $N$ 的素因子分解式为

$ N= p_1^{alpha_1}*p_2^{alpha_2}*...*p_t^{alpha_t} $



$phi(N)=$小于或等于 $N$ 的数中与 $N$ 互素的数的数目$=N*(1-1/p_1)*(1-1/p_2)*...*(1-1/p_t) $

假设 $n<=m$

则所求数为:

$phi(1)+2*(phi(2)+...+phi(n))+phi(n+1)+phi(n+2)+...+phi(m)$

后面的化简就不会了(离开学校多年,很多东西忘记了:L )。

mathe 发表于 2008-11-19 08:59:06

csdn上出现过的:
http://topic.csdn.net/u/20080907/00/d77747a0-7e7f-4ac4-9f9b-902d54795069.html

gxqcn 发表于 2008-11-20 07:48:13

mathe 在上述链接中给出了非常好的算法。:b:

这里转帖一下:

可以通过一个类似筛选法求素数的算法,计算出所有小于n的数x的不同素因子数目pc
如pc=0,pc=pc=pc=pc=1,pc=2
然后对于每个整数d,我们知道矩形$1 <=x <=n-1,1 <=y <=m-1$中,x,y都是d的倍数的数目是$[(n-1)/d]*[(m-1)/d]$
我们要算的就是for(s=0,i=1;i<min(n,m);i++){
        if(pc&1){
                s-=((n-1)/i)*((m-1)/i);
        }else{
                s+=((n-1)/i)*((m-1)/i);
        }
}

zhuceyongde 发表于 2008-11-20 23:43:07

回复 6# gxqcn 的帖子

真没想到这个都能被你找到,那个帖就是我发的,但是他的方法在第四个测试点上就错了,还忘指点一下。
页: [1]
查看完整版本: 关于直线扫描格子问题