●●●●●● と1列に並んだボールがありまして、これを
●●●●●●←←の矢印の方向からぎゅっとつぶします。
この時、各ボールの幅は左隣のボールの幅の n% の幅になります。
つまり、つぶれていないボールの幅が w の時、各ボールの幅は左から順番に、
w * n, w * n * n, w * n * n * n, ......となっていきます。
つぶれていないボールの幅が w とするなら、x個並んだボールの総合的な幅 t は t = w * x になります。
これで、つぶした状態のボールの総合的な幅 tw が与えられた時、各ボールの幅はそれぞれどのように求めたらいいですか。
tw < t の関係が成り立つ事は保証します。
また、n%, x, t, w はそれぞれ事前にわかっています。
分かりにくい質問かもしれませんが、よろしくおねがいします。
要するに代数的に解けない(可能性のある)式を解きたいだけでしょ。
ボール全部の幅 tw は圧縮率 n に対して単調関数なので、
ニュートン法でも二分法でも問題ないぢゃん。
ここは、VCをメインとしてるプログラミングなどを扱ってる掲示板だから
質問する場所を間違えていますよ
ニュートン法・二分法ちょっと調べてみましたが、さっぱり解りません。
とりあえず二分探索っぽくやってみました。
main(void)
{
int i;
int x = 6;
int w = 30;
int t = x * w;
int tw = 150;
double tmp, total = 0;
double s = 0.0, e = (t - tw) / (double)x, m = e / 2;
do{
tmp = 0;
for(i = 1;i<=x;i++){
tmp += w * m * i;
}
if((int)tmp == tw) break;
if(tmp > tw) e = m;
else s = m;
m = s + (e - s) / 2;
}while(tw != (int)tmp);
for(i = 1;i<=x;i++){
total += w * m * i;
printf("%d個目 幅=%f, total=%f\n", i, w * m * i, total);
}
}
言われてみれば、ただのC言語の問題にVCなんて関係ないですね。
BCCでもGCCでもいいわけですし。
もうちょっといろいろと突き詰めたいところですが、これで解決とさせていただきます。
また機会があればそのときはよろしくお願いします。
すみません。 解決チェック入れ忘れてました。
編集 削除別に VC++ 特化な質問限定でなくてもいいと思う。以前にもいっぱいあったし。
せっかく作ったので上げておく。手抜きいっぱいだけど。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define ball_width 100.0
#define ball_count 6
double calc_total_width(double pressure) {
double ball=ball_width*pressure;
double total_width=0;
int i;
for (i=0; i<ball_count; ++i) {
total_width+=ball;
ball*=pressure;
}
return total_width;
}
double binary_search(double min, double max, double (*func)(double), double target) {
double center;
double e;
do {
center=(min+max)/2.0;
e=func(center)-target;
if (e<0) min=center; else max=center;
} while (fabs(e)>0.01);
return center;
}
int main(int argc, char* argv[]) {
double target_width=strtod(argv[1], 0);
printf("%g\n", binary_search(0.0, 1.0, &calc_total_width, target_width));
return 0;
}
>言われてみれば、ただのC言語の問題にVCなんて関係ないですね。
俺は、そんなこといってないし、そんなことも思ってない
そもそも、「C言語で開発してる」なんて情報を、書いてないくせに
あたかも俺がそれを元に発言したかのように解釈しないでくれ
最初の質問には
開発環境も、開発言語も、プログラムに関する疑問も記述も単語も何もない
数学の問題にしか見えない
唯一、掛け算が*で表現されてるぐらいか
> 数学の問題にしか見えない
数学の問題ですよね。
> つまり、つぶれていないボールの幅が w の時、各ボールの幅は左から順番> に、
> w * n, w * n * n, w * n * n * n, ......となっていきます。
初項w、公比n(n/100と書くべきかな)のx番目までの等比数列。
等比数列の和(等比級数)は初項a、公比r、項数nの時
S = a(1-rのn剰)/(1-r)
となることがわかっている。
この関係を元の問題に当てはめると、
tw = w(1-nのx剰)/(1-n)
という関係式がわかる。これに具体的な数値を入れていけば
> 各ボールの幅はそれぞれどのように求めたらいいですか。
はすぐに出るような気がするが。つまり、
左端のボールの幅:w = tw(1-n)/(1-nのx剰)
そのとなり:wn = tw*n(1-n)/(1-nのx剰)
以下省略
何か勘違いしてますか?
間違えた。
> 初項w、公比n(n/100と書くべきかな)のx番目までの等比数列。
初項 w * n だった。
したがって
tw = w*n*(1-nのx剰)/(1-n)
左端のボールの幅:w * n = tw*(1-n)/(1-nのx剰)
そのとなり:w * n * n = tw*n*(1-n)/(1-nのx剰)
でも何か、問題が変。
> また、n%, x, t, w はそれぞれ事前にわかっています。
> 各ボールの幅は左から順番に、w * n, w * n * n, w * n * n * n,
> 各ボールの幅はそれぞれどのように求めたらいいですか。
そのまま計算できるような気がする。
nは不明なんじゃないかな?
まだ何か勘違いしているのかなぁ。
さらに言わせてもらえば もももじゃむ さんのプログラムは
> 各ボールの幅は左から順番に、
> w * n, w * n * n, w * n * n * n, ......となっていきます。
を実現していないように思われます。
> for(i = 1;i<=x;i++){
> total += w * m * i;
> printf("%d個目 幅=%f, total=%f\n", i, w * m * i, total);
> }
> }
w * n, w * n * 2, w * n * 3, ...
ですよね。
これで解決でいいの?
nを求めるのなら、tetrapod さんのプログラムが正しいやり方でしょう。
私が示した tw = w*n*(1-nのx剰)/(1-n) を使う場合でも、n の x 次方程式に
なるので、やはりニュートン法などが必要になるでしょう。