题目链接:点击打开链接
题目大意:给你n个齿轮的坐标以及半径,假设第一个齿轮的转速为1,顺时针转,求当施加力量使得第一个齿轮转动时,其他齿轮是否转动以及转速转动情况。
题目思路:利用BFS从第一个齿轮开始遍历,把与他相邻的齿轮加进队列然后顺着往下扫描即可,暴力模拟可做。
AC代码:
/*
2017年8月26日19:59:41
Gym-100543D
AC
*/
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
const int maxn=1010;
const double eps=1e-8;
int n;
struct Point{
int x,y,r;//坐标 半径
int fz,fm;//分子分母
bool spin;//是否旋转的标志
bool dir;//true: clockwise false conterclockwise
void init(){//初始化
x=y=r=fz=fm=0;
spin=false;
}
}a[maxn];
bool vis[maxn];//访问标记
/*用来约分*/
int gcd(int x, int y)
{
return y ? gcd(y, x % y) : x;
}
/*返回两点之间的距离*/
double dis(int x1,int y1,int x2,int y2){
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
void bfs(){
memset(vis,false,sizeof(vis));
Point p,p1;
queue<Point> q;
/*把齿轮一加入队列*/
p.x=a[1].x;
p.y=a[1].y;
p.r=a[1].r;
p.fz=1;
p.fm=1;
p.spin=true;
p.dir=true;
vis[1]=true;
/*并且更新齿轮一的转速以及方向*/
a[1].fz=1;
a[1].fm=1;
a[1].spin=true;
a[1].dir=true;
/*加入队列*/
q.push(p);
while(!q.empty()){
p1=q.front();
q.pop();
for(int i=1;i<=n;i++){
if(!vis[i]){
int x1,x2,y1,y2;
x1=p1.x;
x2=a[i].x;
y1=p1.y;
y2=a[i].y;
if(abs(dis(x1,y1,x2,y2)-(double)(p1.r+a[i].r)<=eps)){
/*如果这两个圆相切,将这个点加入队列*/
p.x=a[i].x;
p.y=a[i].y;
p.r=a[i].r;
p.spin=true;
p.dir=!(p1.dir);//该圆转的方向与启动的圆方向相反
//算出转速并且约分 简单的高中物理 r1/r2=v1/v2
int fz,fm;
fz=p1.fz*p1.r;
fm=p1.fm*p.r;
int g=gcd(fz,fm);
if(g!=1) fz/=g,fm/=g;
p.fz=fz;
p.fm=fm;
vis[i]=true;//访问标记置为1
//更新这个齿轮的信息
a[i].spin=p.spin;
a[i].dir=p.dir;
a[i].fz=p.fz;
a[i].fm=p.fm;
//进队列
q.push(p);
}
}
}
}
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
//对每个点进行初始化
for(int i=1;i<=n;i++) a[i].init();
for(int i=1;i<=n;i++){
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].r);
}
bfs();
for(int i=1;i<=n;i++){
if(a[i].spin&&a[i].fm){//如果该点能够转动 并且有转速
if(a[i].fm==1){
printf("%d ",a[i].fz);
if(a[i].dir==1){
printf("clockwise\n");
}
else{
printf("counterclockwise\n");
}
}
else{
printf("%d/%d ",a[i].fz,a[i].fm);
if(a[i].dir==1){
printf("clockwise\n");
}
else{
printf("counterclockwise\n");
}
}
}
else printf("not moving\n");
}
}
return 0;
}