Problem:
Problem E:
Spirograph
Some of you might have seen instruments like the figure below.
Figure 1: Spirograph
There are a fixed circle (indicated by
A
in the figure) and a smaller interior circle with some
pinholes (indicated by
B
). By putting a pen point through one of the pinholes and then rolling
the circle
B
without slipping around the inside of the circle
A
, we can draw curves as illustrated
below. Such curves are called
hypotrochoids
.
Figure 2: An Example Hypotrochoid
Your task is to write a program that calculates the length of hypotrochoid, given the radius of
the fixed circle
A
, the radius of the interior circle
B
, and the distance between the
B
’s centroid and the used pinhole.
Input
The input consists of multiple test cases. Each test case is described by a single line in which
three integers
P
,
Q
and
R
appear in this order, where
P
is the radius of the fixed circle
A
,
Q
is the radius of the interior circle
B
, and
R
is the distance between the centroid of the circle
B
and the pinhole. You can assume that 0 ≤
R
<
Q
<
P
≤ 1000.
P
,
Q
, and
R
are separated by
a single space, while no other spaces appear in the input.
The end of input is indicated by a line with
P
=
Q
=
R
= 0.
Output
For each test case, output the length of the hypotrochoid curve. The error must be within
10
-2
(= 0.01).
Sample Input
3 2 1
3 2 0
0 0 0
Output for the Sample Input
13.36
6.28

Submitted solutions:

code_snippet: #include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
const double PI = acos(-1);

int gcd(int a, int b){
    if(a%b==0) return b;
    return gcd(b,a%b);
}

int main(){
    while(1){
        int p,q,r;
        cin >> p >> q >> r;
        if(p == 0) break;

        int rotnum = (r==0)? 1: q/gcd(p-q, q);
        int splitnum = 1e4;
        int n = rotnum*splitnum;
        double dt = 2*PI/splitnum;
        vector<double> arr(n);
        for(int i=0; i<n; i++){
            double t = dt *i;
            double xpt = -(p-q)*sin(t) -r*sin(t*(p-q)/q)*(p-q)/q;
            double ypt =  (p-q)*cos(t) -r*cos(t*(p-q)/q)*(p-q)/q;
            arr[i] = sqrt(xpt*xpt +ypt*ypt);
        }

        double ans = 0;
        for(int i=0; i<n; i++){
            ans += arr[i];
        }
        ans *= dt;
        cout << fixed << setprecision(3);
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 5510
memory_kb: 84540
final_rank: 7

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

const double PI = acos(-1.0);
const int N = 100000;

int main()
{
    for(;;){
        int p, q, r;
        cin >> p >> q >> r;
        if(p == 0)
            return 0;

        if(r == 0){
            double ret = (p - q) * 2.0 * PI;
            printf("%.10f\n", ret);
            continue;
        }

        double theta = 2.0 * PI * q / p;
        double ret = 0.0;
        double x1 = p - q + r;
        double y1 = 0.0;
        for(int i=1; i<=N; ++i){
            double x2 = (p - q) * cos(theta/N*i) + r * cos((p - q) * theta/N*i / q);
            double y2 = (p - q) * sin(theta/N*i) - r * sin((p - q) * theta/N*i / q);
            ret += sqrt(pow(x1 - x2, 2.0) + pow(y1 - y2, 2.0));
            x1 = x2;
            y1 = y2;
        }

        int i = 1;
        while((q * i) % p != 0)
            ++ i;
        ret *= i;

        printf("%.10f\n", ret);
    }
}
accuracy: 1
time_ms: 220
memory_kb: 1200
final_rank: 3

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)n; ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cout<<*i<<" "; cout<<endl; }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int P, Q, R;
double getx(double t){
  return (double)(P - Q) * cos(t) + (double)R * cos(t * (P - Q) / Q);
}
double dx(double t){
  return (double)(P - Q) * (-sin(t)) + (double)R * (P - Q) / Q * (-sin(t * (P - Q) / Q));
}
double gety(double t){
  return (double)(P - Q) * sin(t) - (double)R * sin(t * (P - Q) / Q);
}
double dy(double t){
  return (double)(P - Q) * (cos(t)) - (double)R * (P - Q) / Q * (cos(t * (P - Q) / Q));
}
double dist(double x1, double y1, double x2, double y2){
  return sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
}

int main(){
  while(cin>>P>>Q>>R && P){
    int time = -1;
    for(int k = 1; ; k++){
      if(R == 0){
        time = 1;
        break;
      }
      if(k * (P - Q) % Q == 0){
        time = k;
        break;
      }
    }
    const int ITER = 10000;
    const double delta = 2.0 * time * M_PI / ITER;
    double ans = 0;
    REP(iter, ITER){
      double t = delta * iter;
      ans += sqrt(dx(t) * dx(t) + dy(t) * dy(t)) * delta;
    }
    printf("%.2f\n", ans + EPS);
  }
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 1252
final_rank: 2

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)n; ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cout<<*i<<" "; cout<<endl; }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int P, Q, R;
double getx(double t){
  return (double)(P - Q) * cos(t) + (double)R * cos(t * (P - Q) / Q);
}
double dx(double t){
  return (double)(P - Q) * (-sin(t)) + (double)R * (P - Q) / Q * (-sin(t * (P - Q) / Q));
}
double gety(double t){
  return (double)(P - Q) * sin(t) - (double)R * sin(t * (P - Q) / Q);
}
double dy(double t){
  return (double)(P - Q) * (cos(t)) - (double)R * (P - Q) / Q * (cos(t * (P - Q) / Q));
}
double dist(double x1, double y1, double x2, double y2){
  return sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
}

int main(){
  while(cin>>P>>Q>>R && P){
    int time = -1;
    for(int k = 1; ; k++){
      if(R == 0){
        time = 1;
        break;
      }
      if(k * (P - Q) % Q == 0){
        time = k;
        break;
      }
    }
    const int ITER = 100000;
    const double delta = 2.0 * time * M_PI / ITER;
    double ans = 0;
    REP(iter, ITER){
      double t = delta * iter;
      ans += sqrt(dx(t) * dx(t) + dy(t) * dy(t)) * delta;
    }
    printf("%.2f\n", ans + EPS);
  }
  return 0;
}
accuracy: 1
time_ms: 350
memory_kb: 1252
final_rank: 4

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)n; ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cout<<*i<<" "; cout<<endl; }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int P, Q, R;
double getx(double t){
  return (double)(P - Q) * cos(t) + (double)R * cos(t * (P - Q) / Q);
}
double dx(double t){
  return (double)(P - Q) * (-sin(t)) + (double)R * (P - Q) / Q * (-sin(t * (P - Q) / Q));
}
double gety(double t){
  return (double)(P - Q) * sin(t) - (double)R * sin(t * (P - Q) / Q);
}
double dy(double t){
  return (double)(P - Q) * (cos(t)) - (double)R * (P - Q) / Q * (cos(t * (P - Q) / Q));
}
double dist(double x1, double y1, double x2, double y2){
  return sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
}

int main(){
  while(cin>>P>>Q>>R && P){
    int time = -1;
    for(int k = 1; ; k++){
      if(R == 0){
        time = 1;
        break;
      }
      if(k * (P - Q) % Q == 0){
        time = k;
        break;
      }
    }
    const int ITER = 1000000;
    const double delta = 2.0 * time * M_PI / ITER;
    double ans = 0;
    REP(iter, ITER){
      double t = delta * iter;
      ans += sqrt(dx(t) * dx(t) + dy(t) * dy(t)) * delta;
    }
    printf("%.2f\n", ans + EPS);
  }
  return 0;
}
accuracy: 1
time_ms: 3490
memory_kb: 1280
final_rank: 5

code_snippet: #include<cmath>
#include<cstdio>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

const double PI=acos(-1);

int R,r,d;

double f(double t){
	double a=1-(double)R/r;
	double x_dash=-(R-r)*sin(t)-a*d*sin(a*t);
	double y_dash= (R-r)*cos(t)+a*d*cos(a*t);
	return sqrt(x_dash*x_dash+y_dash*y_dash);
}

int main(){
	for(;scanf("%d%d%d",&R,&r,&d),R;){
		int k;
		if(d==0) k=1; // hypotrochoid が縮退して円になっている
		else{
			for(k=1;k*(r-R)%r!=0;k++);
		}
		double T=2*k*PI; // 周期

		double ans=0;
		int n=10000; // 何等分するか
		rep(i,n){
			double t1=T*i/n,t2=T*(i+1)/n;
			ans+=f((t1+t2)/2)*(t2-t1);
		}
		printf("%.9f\n",ans);
	}

	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 792
final_rank: 1

code_snippet: #include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <memory.h>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <cmath>
using namespace std;

#define rep(i, n) for(int i = 0; i< n; i++)
typedef long long ll;
const double EPS = 1e-8;
const double PI = 2 * acos(0.0);

int gcd(int u, int v){
  while(u > 0){
    if(v > u) swap(u, v);
    u %= v;
  }
  return v;
}

int lcm(int u, int v){
  return u / gcd(u, v) * v;
}

double f(int P, int Q, int R, double theta){
  double a = (double)(Q - P) / Q;
  double dx = -(P - Q) * sin(theta) - a * R * sin(a * theta);
  double dy = (P - Q) * cos(theta) + a * R * cos(a * theta);
  return sqrt(dx*dx + dy*dy);
}

double calc(int P, int Q, int R){

  double end = (double)Q / P * 2 * PI;
  double res = 0;
  const int cnt = 500000;
  for(int i = 0; i < cnt; i++){
    double theta = end * i / cnt;
    double dtheta = end / cnt;
    res += dtheta * (f(P, Q, R, theta) + 4 * f(P, Q, R, theta + dtheta / 2)
		     + f(P, Q, R, theta + dtheta)) / 6;
  }
  return res;
}
int main(){
  int P, Q, R;
  while(cin >> P >> Q >> R && (P || Q || R)){
    double res = calc(P, Q, R);
    cout << fixed << setprecision(2);
    if(R == 0) cout << res * P / Q << endl;
    else cout << res * lcm(P, Q) / Q << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 4210
memory_kb: 932
final_rank: 6