去年九月校内选拔赛用的这套题,然后这一题没过,就呵呵了><
首先可以根据圆心距判断是否相切,只有相切的wheel才会引发转动。相切的wheel切点线速度相等, set w=角速度,则w1*r1=w2*r2, p/q=w, thus (p1/q1)*r1=(p2/q2)*r2, (p1*r1)/(q1*r2)=p2/q2 and 方向相反. 可以用BFS沿着相切的wheel逐个计算p/q。
现场没有过是因为BFS中求出下一个wheel的p/q之后没有除以gcd化简,然后就爆long long WA了>< 当时还以为是gcd模板出错,智硬得忧伤==
#include<iostream>
#include<stdlib.h>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstring>
using namespace std;
const int maxn=1010;
int T;
int n;
const double eps=1e-4;
class circle
{
public:
int x;
int y;
int r;
int idx;
int p;
int q;
int dir;
public:
circle()
{
x=0;
y=0;
r=0;
idx=0;
q=0;
p=0;
dir=0;
}
};
circle whe[maxn];
int cut[maxn][maxn];
bool vis[maxn];
class rot
{
public:
int p;
int q;
int dir;//1 for cw, 2 for ccw
public:
rot()
{
q=0;
p=0;
dir=0;
}
};
rot ans[maxn];
long long centerdis(circle a,circle b)
{
long long dis=(long long)(a.x-b.x)*(a.x-b.x)+(long long)(a.y-b.y)*(a.y-b.y);
//return sqrt(dis);
return dis;
}
bool iscut(circle a,circle b)
{
long long dis=centerdis(a,b);
long long rad=a.r+b.r;
long long rad2=rad*rad;
if(fabs(rad2-dis)<eps)
//if(fabs(rad-dis)<eps)
{
return true;
}
return false;
}
int kgcd(int a,int b)
{
if(a==0) return b;
if(b==0) return a;
if(!(a&1)&&!(b&1)) return kgcd(a>>1,b>>1)<<1;
else if(!(b&1)) return kgcd(a,b>>1);
else if(!(a&1)) return kgcd(a>>1,b);
else return kgcd(abs(a-b),min(a,b));
}
void init()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j) continue;
if(iscut(whe[i],whe[j])==true)
{
cut[i][j]=1;
cut[j][i]=1;
}
}
}
}
void bfs(int st)
{
queue<circle>que;
while(!que.empty()) que.pop();
que.push(whe[st]);
while(!que.empty())
{
circle now= que.front();
que.pop();
vis[now.idx]=true;
for(int i=1;i<=n;i++)
{
if(i==now.idx) continue;
if(vis[i]==true) continue;
if(cut[now.idx][i]==1)
{
circle next=whe[i];
next.p=now.r*now.p;
next.q=next.r*now.q;
int g=kgcd(next.p,next.q);
next.p=next.p/g;
next.q=next.q/g;
if(now.dir==1)
{
next.dir=2;
}
else if(now.dir==2)
{
next.dir=1;
}
vis[next.idx]=true;
ans[next.idx].dir=next.dir;
ans[next.idx].p=next.p;
ans[next.idx].q=next.q;
que.push(next);
}
}
}
}
int gcd(int x,int y)
{
if(x<y) return gcd(y,x);
if(y==0)
{
return x;
}
else
{
if(!(x&2))
{
if(!(y%2)) return 2*gcd(x>>1,y>>1);
else return gcd(x>>1,y);
}
else
{
if(!(y%2)) return gcd(x,y>>1);
else return gcd(y,x-y);
}
}
}
int gcd2(int a,int b)
{
if(a<b) swap(a,b);
int t;
if(a<0) a=-a;
if(b<0) b=-b;
if(!b) return a;
while(t=a%b)
{
a=b;
b=t;
}
return b;
}
int main()
{
freopen("all.in","r",stdin);
freopen("myc.out","w",stdout);
scanf("%d",&T);
for(int ca=1;ca<=T;ca++)
{
scanf("%d",&n);
memset(cut,0,sizeof(cut));
memset(vis,false,sizeof(vis));
memset(whe,0,sizeof(whe));
memset(ans,0,sizeof(ans));
for(int i=1;i<=n;i++)
{
scanf("%d %d %d",&whe[i].x,&whe[i].y,&whe[i].r);
whe[i].idx=i;
}
whe[1].dir=1;
whe[1].p=1;
whe[1].q=1;
ans[1].p=1;
ans[1].q=1;
ans[1].dir=1;
init();
bfs(1);
for(int i=1;i<=n;i++)
{
if(ans[i].dir==0)
{
printf("not moving\n");
continue;
}
//int g=gcd2(ans[i].p,ans[i].q);
//cout<<g<<endl;
//if(ans[i].p<ans[i].q)
int g=kgcd(ans[i].p,ans[i].q);
ans[i].p=ans[i].p/g;
ans[i].q=ans[i].q/g;
// if(ans[i].p==1&&ans[i].q==1)
// {
// printf("1 ");
// }
// else if(ans[i].p!=1&&ans[i].q==1)
// {
// printf("%d ",ans[i].p);
// }
if(ans[i].q==1)
{
printf("%d ",ans[i].p);
}
else if(ans[i].q!=1)//ans[i].p!=1&&
{
printf("%d/%d ",ans[i].p,ans[i].q);
}
if(ans[i].dir==1)
{
printf("clockwise\n");
}
else if(ans[i].dir==2)
{
printf("counterclockwise\n");
}
}
}
return 0;
}