ACM考题一道,有兴趣的看一看,看看你的能力

时间:2022-09-28 14:12:34
问题描述:
两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面。它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止。可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置。不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的。但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的。为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面。
我们把这两只青蛙分别叫做青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方向,单位长度1米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是x,青蛙B的出发点坐标是y。青蛙A一次能跳m米,青蛙B一次能跳n米,两只青蛙跳一次所花费的时间相同。纬度线总长L 米。现在要你求出它们跳了几次以后才会碰面。
Input
输入只包括一行5个整数x,y,m,n,L,其中x≠y < 2000000000,0 < m、n < 2000000000,0 < L < 2100000000。
Output
输出碰面所需要的跳跃次数,如果永远不可能碰面则输出一行"Impossible"
------------------------------------------------------------------------------------------------------------

本人编的代码分析:
ax表示青蛙A的开始位置,by是表示青蛙B的开始位置,am是青蛙A一步跳的距离,bn是青蛙B一步跳的距离,L是总的长度,cout记录步数
可能存在问题分析
1.判断永不碰面的条件(设走的步数为t,这ax-by=(am-bn)*t,追击问题,所以t=(ax-by)/(am-bn),t必须是整数,后式必须被正出)
2.因为x≠y < 2000000000,0 < m、n < 2000000000,0 < L < 2100000000,代码中的加法ax=((ax+am)+L)%L和by=((by+bn)+L)%L,有可能越界,

还请高手帮忙问题是出在哪里......
---------------------------------------------------------------------------------
#include<stdio.h>
void main()
{
long  ax,by,am,bn,L,cout=0;
scanf("%ld%ld%ld%ld%ld",&ax,&by,&am,&bn,&L);

if(((ax-by)%(am-bn)!=0)||(ax==by)) 
printf("Impossible");
else
{
while(ax!=by)
{
cout++;
ax=((ax+am)+L)%L;
by=((by+bn)+L)%L;
}
printf("%ld",cout);
}

}

11 个解决方案

#1


if(((ax-by)%(am-bn)!=0)||(ax==by)) 
printf("Impossible"); 

青蛙可以在套圈之后相遇吧?

#2


判断是否能相遇的条件应该是(num * m - num * n - (y - x)) % L == 0吧?
自己写了一个

#include<stdio.h>
int meet(long m, long n, long x, long y, long L, long *num)
{
        int zhou;
        *num = 0;
        while (1)
        {
                for(zhou = 0; zhou <= ((*num * m) / L + 1); )
                {
                        if (((*num * m - *num * n - (y - x)) % L ) == 0)
                                return 1;
                        else
                                (*num)++;

                        if (((*num + 1) * m / L) != (*num * m /L))
                                zhou++;
                }
                return 0;
        }
}
int main(void)
{
        long int num;
        long int m, n, x, y, L;
        int flag;
                                                                                
        printf("enter m n x y L:");
        scanf("%ld %ld %ld %ld %ld",&m,&n,&x,&y,&L);
        flag = meet(m,n,x,y,L,&num);
        if(flag)
                printf("%ld\n",num);
        else
                printf("Impossible\n");
        return 0;
}

不知有问题没,欢迎指点,觉得还有更好的算法,没想出来,期待高手!

#3


mt+x=nt+y;  即(m-n)t+x-y=0; 才行

另外没有说明是不是要考虑绕圈,如果要考虑则要加上判断,这个要处理越界MS比较麻烦了

#4


肯定要考虑绕圈................

#5


up

#6


这道题我见过,好像是北大ACM吧,我当时没有做。感觉有点难。

#7


ACM程序也不是很难啊~~

#8


简单地想了下:
1,如果m=n,则不可能碰面,否则计算2只青蛙的速度差P;碰面时跳的次数NUM = 0;
2,计算速度快的青蛙到速度慢的青蛙间的距离Q
3,如果Q % P == 0,则2只青蛙碰面,且次数为MUM + Q/P,否则累加跳的次数TMP = Q/P + 1,NUM += TMP;
4,重新计算速度快的到速度慢的青蛙的距离Q = L - (P*TMP - Q);
5,重复步骤2

可以设置当NUM大于某个值时,退出计算

#9


简单地想了下:
1,如果m=n,则不可能碰面,否则计算2只青蛙的速度差P;碰面时跳的次数NUM = 0;
2,计算速度快的青蛙到速度慢的青蛙间的距离Q
3,如果Q % P == 0,则2只青蛙碰面,且次数为MUM + Q/P,否则累加跳的次数TMP = Q/P + 1,NUM += TMP;
4,重新计算速度快的到速度慢的青蛙的距离Q = L - (P*TMP - Q);
5,重复步骤2

可以设置当NUM大于某个值时,退出计算

#10


非常清晰的丝路,^_^
其实就是一个整除问题,退出条件就是跳了M和N的最小公倍数圈都不能碰面,因为这个时候他们都回到原来的地方了。
引用 10 楼 ltttklyzy 的回复:
简单地想了下: 
1,如果m=n,则不可能碰面,否则计算2只青蛙的速度差P;碰面时跳的次数NUM = 0; 
2,计算速度快的青蛙到速度慢的青蛙间的距离Q 
3,如果Q % P == 0,则2只青蛙碰面,且次数为MUM + Q/P,否则累加跳的次数TMP = Q/P + 1,NUM += TMP; 
4,重新计算速度快的到速度慢的青蛙的距离Q = L - (P*TMP - Q); 
5,重复步骤2 

可以设置当NUM大于某个值时,退出计算

#11


一般般,像教本上的题.

#1


if(((ax-by)%(am-bn)!=0)||(ax==by)) 
printf("Impossible"); 

青蛙可以在套圈之后相遇吧?

#2


判断是否能相遇的条件应该是(num * m - num * n - (y - x)) % L == 0吧?
自己写了一个

#include<stdio.h>
int meet(long m, long n, long x, long y, long L, long *num)
{
        int zhou;
        *num = 0;
        while (1)
        {
                for(zhou = 0; zhou <= ((*num * m) / L + 1); )
                {
                        if (((*num * m - *num * n - (y - x)) % L ) == 0)
                                return 1;
                        else
                                (*num)++;

                        if (((*num + 1) * m / L) != (*num * m /L))
                                zhou++;
                }
                return 0;
        }
}
int main(void)
{
        long int num;
        long int m, n, x, y, L;
        int flag;
                                                                                
        printf("enter m n x y L:");
        scanf("%ld %ld %ld %ld %ld",&m,&n,&x,&y,&L);
        flag = meet(m,n,x,y,L,&num);
        if(flag)
                printf("%ld\n",num);
        else
                printf("Impossible\n");
        return 0;
}

不知有问题没,欢迎指点,觉得还有更好的算法,没想出来,期待高手!

#3


mt+x=nt+y;  即(m-n)t+x-y=0; 才行

另外没有说明是不是要考虑绕圈,如果要考虑则要加上判断,这个要处理越界MS比较麻烦了

#4


肯定要考虑绕圈................

#5


up

#6


这道题我见过,好像是北大ACM吧,我当时没有做。感觉有点难。

#7


ACM程序也不是很难啊~~

#8


简单地想了下:
1,如果m=n,则不可能碰面,否则计算2只青蛙的速度差P;碰面时跳的次数NUM = 0;
2,计算速度快的青蛙到速度慢的青蛙间的距离Q
3,如果Q % P == 0,则2只青蛙碰面,且次数为MUM + Q/P,否则累加跳的次数TMP = Q/P + 1,NUM += TMP;
4,重新计算速度快的到速度慢的青蛙的距离Q = L - (P*TMP - Q);
5,重复步骤2

可以设置当NUM大于某个值时,退出计算

#9


简单地想了下:
1,如果m=n,则不可能碰面,否则计算2只青蛙的速度差P;碰面时跳的次数NUM = 0;
2,计算速度快的青蛙到速度慢的青蛙间的距离Q
3,如果Q % P == 0,则2只青蛙碰面,且次数为MUM + Q/P,否则累加跳的次数TMP = Q/P + 1,NUM += TMP;
4,重新计算速度快的到速度慢的青蛙的距离Q = L - (P*TMP - Q);
5,重复步骤2

可以设置当NUM大于某个值时,退出计算

#10


非常清晰的丝路,^_^
其实就是一个整除问题,退出条件就是跳了M和N的最小公倍数圈都不能碰面,因为这个时候他们都回到原来的地方了。
引用 10 楼 ltttklyzy 的回复:
简单地想了下: 
1,如果m=n,则不可能碰面,否则计算2只青蛙的速度差P;碰面时跳的次数NUM = 0; 
2,计算速度快的青蛙到速度慢的青蛙间的距离Q 
3,如果Q % P == 0,则2只青蛙碰面,且次数为MUM + Q/P,否则累加跳的次数TMP = Q/P + 1,NUM += TMP; 
4,重新计算速度快的到速度慢的青蛙的距离Q = L - (P*TMP - Q); 
5,重复步骤2 

可以设置当NUM大于某个值时,退出计算

#11


一般般,像教本上的题.