首页 > 代码库 > Problem E 圆环的转动问题 (14年内蒙古省赛题)
Problem E 圆环的转动问题 (14年内蒙古省赛题)
1115: Problem E 圆环的转动问题
时间限制: 1 Sec 内存限制: 128 MB提交: 58 解决: 6
[提交][状态][讨论版]
题目描述
已知圆环有如下特性: 1.一个转动着的圆环会带动与其相切的圆环同时转动。 2.两个相切圆环在切点处不会发生滑动。 开始时,平面上有两个静止的圆环(输入数据保证两个圆不会相交或重合)。 后加一外力,使得第一个圆环以角速度W匀速转动。 求此时第二个圆环的角速度。
输入
输入包含多组数据。 对于每组数据: 第一行有两个整数 : X1,Y1 , R1(第一个圆环的坐标及半径) 第二行有两个整数 : X2,Y2 , R2(第二个圆环的坐标及半径) 第三行有一个整数 : W ( 第一个圆环的角速度 ,负数表示反方向转动 ) X1,Y1,X2,Y2为整数且范围在[0,10^8]内 R1,R2为整数且 0 < R1,R2 < 10^8 W为整数 且 -10^8 < W < 10^8
输出
请输出第二个圆环的角速度,若不是整数以最简分数形式输出(参见样例)。 每组数据输出一行。
样例输入
0 0 1
2 0 1
-1
0 0 3
5 0 2
1
样例输出
1
-3/2
提示
这道题算是一道比较简单的计算几何题;第一次做的时候,忘记考虑内切的情况了,提交一直wa,开始一直也没找到什么错误;
第二次做的时候,思路已经很清晰了:
主要有三种情况:相离:圆心之间的距离大于两个半径之和的距离(小于两个半径之差)
外切:圆心之间的距离==两个半径之和的距离 (w2的方向和w1的方向相反)
内切:圆心之间的距离==两个半径之差的距离 (w2的方向和w1的方向相同)
还有就是要考虑输出形式的问题:如果可以整除就直接输出;
否则就按最简分数形式输出,(求他们之间的最大公约数,然后再输出)
第二次做的时候,代码在思路上没有问题了,但是还是wa,(更加找不到错误在哪了),后来,重新看了一遍,发现当w=0时,直接输出 0这个隐含条件一直没有处理,在判断相离的时候,添加上这个条件,a了。(坑爹啊!!)一定要注意细节的问题,以后做题一定要着重题目的思路,锻炼思维的能力!
下面是代码:
#include <cstdio> #include <string> #include <iostream> #include <cmath> typedef long long ll; using namespace std; ll gcd( ll a,ll b) //求最大公约数 { ll r; while(b!=0) { r=a%b; a=b; b=r; } return a; } ll square(ll x) //求平方 { return x*x; } ll distance(ll x1,ll y1,ll x2,ll y2) //两点之间的距离 { return square(x1-x2)+square(y1-y2); } int main() { ll x1,y1,r1,x2,y2,r2,w,v1,temp; while(cin>>x1>>y1>>r1>>x2>>y2>>r2>>w) { v1=w*r1; ll dis=distance(x1,y1,x2,y2); if(dis>square(r1+r2) || dis<square(r1-r2) ||w==0)//相离 { printf("0\n"); } else if(dis==square(r1+r2))//外切 { if(w>0) printf("-"); if(v1%r2==0) printf("%lld\n",(ll)abs(v1)/r2); else { temp=gcd((ll)abs(v1),r2); printf("%lld/%lld\n",(ll)abs(v1)/temp,r2/temp); } } else if(dis==square(r1-r2))//内切 { if(w<0) printf("-"); if(v1%r2==0) printf("%lld\n",(ll)abs(v1)/r2); else { temp=gcd((ll)abs(v1),r2); printf("%lld/%lld\n",(ll)abs(v1)/temp,r2/temp); } } } return 0; }
Problem E 圆环的转动问题 (14年内蒙古省赛题)