3789 - 齿轮

通过次数

0

提交次数

0

时间限制 : 1 秒 内存限制 : 128 MB

LongDD 新买的机器的内部结构大概算世界上最混乱的了,它不象普通的机器一

样有明确的内部传动装置,而是,N (2 <= N <= 1050)个齿轮互相作用,每个齿轮

都可能驱动着多个齿轮。

LongDD 记录了对于每个齿轮 i,记录了它的 3 个参数:X_iY_i 表示齿轮中心

的位置坐标(-5000 <= X_i <= 5000; -5000 <= Y_i <= 5000)R_i 表示该齿轮的

半径(3 <= R_i <= 800)。驱动齿轮的位置为 0,0,并且 FJ 也知道最终的工作齿轮

位于 X_t,Y_t

驱动齿轮顺时针转动,转速为 10,000 /小时。你的任务是,确定传动序列中

所有齿轮的转速。传动序列的定义为,能量由驱动齿轮传送到工作齿轮的过程中用

到的所有齿轮的集合。对能量传送无意义的齿轮都应当被忽略。在一个半径为 Rd

转速为 S /每小时的齿轮的带动下,与它相接的半径为 Rx 的齿轮的转速将为

-S*Rd/Rx /小时。 S 前的负号的意思是,一个齿轮带动的另一个齿轮的转向会与它

的转向相反。

LongDD 只对整个传动序列中所有齿轮速度的绝对值之和感兴趣,你的任务也就

相应转化成求这个值。 机器中除了驱动齿轮以外的所有齿轮都被另外某个齿轮带动,

并且不会出现 2 个不同的齿轮带动同一个齿轮的情况。

相信你能轻易地写个程序来完成这些计算:)

题目输入

* 1 : 3 个用空格隔开的整数:NX_tY_t

* 2..N+1 : i+1 描述了齿轮 i 的位置及半径:X_iY_i,以及 R_i

题目输出

1: 输出所有在传动中起到作用的齿轮转速的绝对值,包括驱动齿轮和工作齿轮。只需要输出的整数部分,与答案相差不超过1即可。

输入/输出样例

输入格式

4 32 54
0 0 10
0 30 20
32 54 20
-40 30 20

输出格式

20000

C++解答

#define MAXN 1100UL

#define D(x) ((double)(x))

#include <cstdio>
#include <queue>
#include <cmath>

using namespace std;

queue<int> que;

int x[MAXN],y[MAXN],r[MAXN],p,s,t,n,xt,yt;

bool ex[MAXN];

double dx[MAXN][2],eps=0.1;

double ABS(double a){
	return a>0?a:-a;
}

double Cal(int a,int b){
	return sqrt(D(x[a]-x[b])*D(x[a]-x[b])+D(y[a]-y[b])*D(y[a]-y[b]));
}

int main(){
	scanf("%d%d%d",&n,&xt,&yt);
	for(int i=1;i<=n;i++){
		scanf("%d%d%d",&x[i],&y[i],&r[i]);
		if(x[i]==0&&y[i]==0){
			s=i;
		}
		else if(x[i]==xt&&y[i]==yt){
			t=i;
		}
	}
	//bfs
	dx[s][0]=dx[s][1]=10000.0;
	que.push(s);ex[s]=1;
	while(!que.empty()){
		p=que.front();que.pop();
		for(int i=1;i<=n;i++){
			if(!ex[i]&&i!=p){
				if(ABS(D(r[i]+r[p])-Cal(i,p))<=eps){
					ex[i]=1;dx[i][0]=dx[p][0]*D(r[p])/D(r[i]);
					dx[i][1]=dx[i][0]+dx[p][1];
					if(i==t){
						printf("%d",(int)dx[t][1]);
						return 0;
					}
					que.push(i);
				}
			}
		}
	}
	return 0;
}