解いた問題のソースコードと解説など。


POJ 1905 Expanding Rods

問題

長さLの鉄線をn度で熱すると長さがL*(1+n*C)に変化する。Cは膨張係数である。この鉄線を向かい合わせの壁に取り付けて熱すると膨張して弧を描くようにしなる。熱したときの鉄線の中心部の縦方向への変位を求めよ。

やりかた

弧になったときの弧長をL'、中心角をθとし、半径をxとすると答えはx(1 - \cos \frac{\theta}{2})で求められる。弧長L'はL'=x\thetaと計算でき、扇形の半径ともともとの鉄線の長さLとは2x\sin \frac{\theta}{2}=Lという関係がある。これらから\frac{\sin \frac{\theta}{2}}{\theta} = \frac{L}{2L'} = \frac{1}{2(1 + nC)}と変形する。ここからθを求めるには二分探索を使う。
θが求まればあとは代入して計算するだけ。
精度が少し厳しいのでいつもより多めにループした。
以下ソース。

int main(int argc, char **argv){
  double l, n, c;
  while(cin >> l >> n >> c){
    if(l < 0 && n < 0 && c < 0) break;
    
    double ub = acos(( double)-1), lb = 0;
    for(int i = 0; i < 10000; i++){
      double mid = (ub + lb) * 0.5;
      double x = sin(0.5 * mid) / mid;
      double y = 0.5 / (1.0 + n * c);
      if(x > y) lb = mid;
      else ub = mid;
    }
    cout.precision(3);
    cout.setf(ios::fixed);
    cout << ((1.0 - cos(0.5 * ub)) * l * (1.0 + n * c) / ub) << endl;
  }
  return 0;
}
Get up! 明日のSUPER ST@R!