関数の最大値

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
遠藤

関数の最大値

#1

投稿記事 by 遠藤 » 14年前

f=n*n*n+m*(m+1)*(m+2)/6を使って、入力された数字を越えないようなできるだけ大きい数字を出力するにはどうすればいいでしょうか。
(例:入力された数字が9なら、n=3,m=0)


C言語初心者です。
考えてみたのですがうまくいきません。アドバイスお願いします。

コード:

#include<stdio.h>

main()
{
  int n,x,m1,m2;
  int ans,ans1,ans2,ans3,max;

  scanf("%d",&x);


   for(n=1;n<1000;n++){
    if(x>=n*n*n && x<(n+1)*(n+1)*(n+1))
      ans1=n*n*n;


    if(x>=n*(n+1)*(n+2)/6 && x<(n+1)*(n+2)*(n+3)/6)
      ans2=n*(n+1)*(n+2);
   }

    for(m1=0;m1<1000;m1++){
      for(m2=0;m2<1000;m2++){
	if(x>=m1*m1*m1+m2*(m2+1)*(m2+2)/6 && x<(m1+1)*(m1+1)*(m1+1)+(m2+1)*(m2+2)*(m2+3)/6)
      ans3=m1*m1*m1+m2*(m2+1)*(m2+2)/6;
      }}

      max=ans1;
      if(ans2>max)
	max=ans2;
      if(ans3>max)
	max=ans3;

  printf("%d\n",max);
}


beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 関数の最大値

#2

投稿記事 by beatle » 14年前

遠藤 さんが書きました:f=n*n*n+m*(m+1)*(m+2)/6を使って、入力された数字を越えないようなできるだけ大きい数字を出力するにはどうすればいいでしょうか。
(例:入力された数字が9なら、n=3,m=0)
すみませんが、この時点でわけがわかりません。
入力が9なら9を超えてはいけないのですよね?
f(n,m)=n*n*n+m*(m+1)*(m+2)/6
のとき
f(3,0) = 3*3*3 + 0*(0+1)*(0+2)/6 = 27
ですから、この時点で9を超えているのです。

「入力された数字が9なら、n=3,m=0」はどこから出てきた数字でしょうか。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 関数の最大値

#3

投稿記事 by beatle » 14年前

それから、一度mixcpp/投稿前チェックリストの「チェック3 : インデントを揃えよう」をお読みください。

遠藤

Re: 関数の最大値

#4

投稿記事 by 遠藤 » 14年前

あ、間違えました・・・
入力された数字が27ならn=3,m=0です。
ボケてました

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 関数の最大値

#5

投稿記事 by beatle » 14年前

遠藤さんが考えたやり方で、どんな場合も正しい答えを出すのかどうかは確認していませんが、
一つ明らかなミスを発見しました。
単純なミスですが、6で割り忘れている箇所があります。

non
記事: 1097
登録日時: 15年前

Re: 関数の最大値

#6

投稿記事 by non » 14年前

>入力された数字を越えないようなできるだけ大きい数字

プログラムを読んでいないのですが、
何が大きい数字なのですか?nですかmですか?
non

ふりかけ

Re: 関数の最大値

#7

投稿記事 by ふりかけ » 14年前

n,mは整数でいいのでしょうか。
そのうえで設定値を超えない最大の解を見つけたいということでしょうか。
だとすればアルゴリズムは問題なさそうですが、何がうまくいかないのですか?

個人的には何に使うプログラムなのかも知りたいです。

かずま

Re: 関数の最大値

#8

投稿記事 by かずま » 14年前

遠藤 さんが書きました: 考えてみたのですがうまくいきません。アドバイスお願いします。
質問するときは、具体的にデータを提示してください。例えば、
「入力が 11 だと出力が 10 になるが、n=1, m=3 で f= 11 となるので、
期待する出力は 11 です。」というように。

どこが悪いのかというと、m1 と m2 の forループで、
m1=1, m=3 のとき、ans3=11 になるのに、そのあと
m1=2, m=1 のとき、ans3=9 になってしまうから、ans3=11 が捨てられ、
最終結果が ans2=10 (n=0, m=3) になっているのです。

ans1 は m=0 のときの値、
ans2 は n=0 のときの値。
ans3 で n も m も 0 から始めているのだから ans1 や ans2 は不要。
ans3 を求める時、以前の ans3 より大きいかどうかで max を決めればよいでしょう。

さて、私なら次のようなプログラムを書きます。

コード:

#include <stdio.h>
#include <math.h>

void proc(int x)
{
    int f, n, m, t, f1 = 0, n1 = 0, m1 = 0;

    for (m = 0; t = m * (m+1) * (m+2) / 6, t <= x; m++) {
        n = pow(x - t + 0.5, 1.0 / 3);
        f = n*n*n + t;
        if (f > f1) f1 = f, n1 = n, m1 = m;
    }
    printf("x=%d, f=%d, n=%d, m=%d\n", x, f1, n1, m1);
}

int main(void)
{
    int x;
    while (printf("> "), scanf("%d", &x) === 1) proc(x);
    return 0;
}
pow を呼ぶとき +0.5 していますが、これは +0.1 でも +0.9 でも構いません。
これがないと、64 の立方根が 3.999..... になって n が 4 になってくれないからです。

non
記事: 1097
登録日時: 15年前

Re: 関数の最大値

#9

投稿記事 by non » 14年前

ああ、そういう課題でしたか。
私なら、こうしますね。(かずまさんのプログラムを流用しました)

コード:

void proc(int x)
{
    int f, n, m, t, f1 = 0, n1 = 0, m1 = 0;
 
    for (m = 0; t = m * (m+1) * (m+2) / 6, t <= x; m++) {
//        n = pow(x - t + 0.5, 1.0 / 3);
		for(n=0;f = n*n*n + t, f <= x; n++)
			if (f > f1) f1 = f, n1 = n, m1 = m;
    }

    printf("x=%d, f=%d, n=%d, m=%d\n", x, f1, n1, m1);
}
non

遠藤

Re: 関数の最大値

#10

投稿記事 by 遠藤 » 14年前

コード:

#include<stdio.h>

main()
{
  int n,x,m1,m2;
  int ans,ans1=0;

  scanf("%d",&x);

    for(m1=0;m1<1000;m1++){
      for(m2=0;m2<1000;m2++){
	if(x>=m1*m1*m1+m2*(m2+1)*(m2+2)/6 && x<(m1+1)*(m1+1)*(m1+1)+(m2+1)*(m2+2)*(m2+3)/6)
         ans=m1*m1*m1+m2*(m2+1)*(m2+2)/6;
	   if(ans>ans1)
           ans1=ans;

                            }
                          }
  printf("%d\n",ans1);
}



説明が足りず分かり難くなってしまい、申し訳ありません。
みなさんの助言でなんとか解くことが出来ました。ありがとうございました。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 関数の最大値

#11

投稿記事 by beatle » 14年前

解決したら解決マークをお願いします。

1つアドバイスすると、
int f(int n, int m);
という関数を作ったらすっきりします。

遠藤

Re: 関数の最大値

#12

投稿記事 by 遠藤 » 14年前

すみません。解決マーク押しました。

閉鎖

“C言語何でも質問掲示板” へ戻る