質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Q&A

解決済

2回答

3617閲覧

ある税込み価格になる最大の税抜き価格の求め方

grape_ll

総合スコア83

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

0グッド

0クリップ

投稿2020/05/30 12:44

編集2020/06/04 13:52

問題

消費税は売価に比例した定率を課す税である.

私たちの店では,以下のルールによって税込価格を計算する.

消費税率が x% のとき, 税抜価格が p 円である商品の税込価格は, p (100+x) / 100 円を小数点以下切り捨てたものである.
複数の商品についてまとめて支払う際の税込合計価格は,個々の商品の税込価格の合計額とする.
消費税率はしょっちゅう変更される. 私たちの店の会計係は, 「税込合計価格が同じだった2商品の組が,消費税率の変更後に異なる税込合計価格になりうる」 ことに気付いた. たとえば, 消費税率が 5% から 8% に上がると,引上げ前に税込合計価格 105 円であった2商品の税込合計金額は, 下表に示すとおり 107 円,108 円,109 円のいずれかとなる.

2商品の税抜価格 消費税率 5% 時の税込価格 消費税率 8% 時の税込価格
20, 80 21 + 84 = 105 21 + 86 = 107
2, 99 2 + 103 = 105 2 + 106 = 108
13, 88 13 + 92 = 105 14 + 95 = 109
会計係が消費税率変更の影響を調査している. 2つの商品の消費税率変更前の税込合計価格を元に, 新消費税率での税込合計価格が最大いくらになるかを計算するプログラムを作って欲しい.

【入力】
複数のデータセットからなる. 各データセットは1行からなり, その行は空白で区切られた3つの整数 x, y, s からなる. x は変更前の消費税率(パーセント), y は変更後の消費税率(パーセント), s は消費税率変更前の 2 商品の税込合計価格である. これらの整数は,0 < x < 100, 0 < y < 100, 10 < s < 1000,x ≠ y を満たす. 商品の税抜価格として 1 円から s -1 円のすべてを考慮に入れよ.

入力の終わりは,空白で区切られた3つのゼロからなる行によって示される.

【出力】
各データセットについて, 消費税率が y% になったときにとりうる税込合計価格の最大値を1行で出力せよ.
(最後の行の末尾にも改行を出力すること。)

【例】
入力例
5 8 105
8 5 105
1 2 24
99 98 24
12 13 26
1 22 23
1 13 201
13 16 112
2 24 50
1 82 61
1 84 125
1 99 999
99 1 999
98 99 999
1 99 11
99 1 12
0 0 0

出力例
109
103
24
24
26
27
225
116
62
111
230
1972
508
1004
20
7

質問内容(解決:下の追記に新たな問題点を書かせていただきました)

前の税率で税込み価格から税抜き価格になおすときに,その税込み価格になる最大の税抜き価格の計算がうまくいきません.どのように工夫すればうまくいくのか教えていただきたいです.よろしくお願いします.

旧コード

C

1#include<stdio.h> 2#include<math.h> 3int main(void){ 4 int a[100000],b[100000],c[100000],ans; 5 int cal,ori; 6 double prerate,postrate; 7 int i=0; 8 while(1){ 9 scanf("%d %d %d",&a[i],&b[i],&c[i]); 10 ans=0; 11 if(a[i]==0&&b[i]==0&&c[i]==0) break; 12 int j; 13 prerate=1+(double)a[i]/100; 14 postrate=1+(double)b[i]/100; 15 printf("%f ",prerate); 16 ori=c[i]/prerate; 17 int k=1; 18 while(1){ 19 printf("%d ",(int)((ori+k)*prerate)); 20 if((int)((ori+k)*prerate)>c[i]) break; 21 else ori+=k; 22 } 23 printf("(%d) ",ori); 24 for(j=1;j<ori;j++){ 25 if(j==1) ans=j*(double)(1+b[i]/100)+(ori-j)*postrate; 26 else if((cal=j*(double)(1+b[i]/100)+(ori-j)*postrate)<ans) break; 27 else if((cal=j*(double)(1+b[i]/100)+(ori-j)*postrate)>ans) ans=cal; 28 } 29 printf("%d\n",ans); 30 i++; 31 } 32 return 0; 33}

実行結果

5 8 105
1.050000 105 106 (100) 107
8 5 105
1.080000 105 106 (98) 102
1 2 24
1.010000 24 25 (24) 24
99 98 24
1.990000 25 (12) 22
1 13 201
1.010000 202 (199) 224
0 0 0


ご指摘いただいて書き直したコード(まだ正確なものは表示されない)

C

1#include<stdio.h> 2#include<math.h> 3int main(void){ 4 int a[1000],b[1000],c[1000],ans; 5 int cal,ori; 6 int i=0; 7 while(1){ 8 scanf("%d %d %d",&a[i],&b[i],&c[i]); 9 ans=0; 10 if(a[i]==0&&b[i]==0&&c[i]==0) break; 11 int j; 12 ori=(c[i]*100+99)/(100+a[i]); 13 printf("(%d) ",ori); 14 double postrate=1+(double)b[i]/100; 15 for(j=1;j<ori;j++){ 16 if(j==1) ans=j*(double)(1+b[i]/100)+(ori-j)*postrate; 17 else if((cal=j*(double)(1+b[i]/100)+(ori-j)*postrate)<ans) break; 18 else if((cal=j*(double)(1+b[i]/100)+(ori-j)*postrate)>ans) ans=cal; 19 } 20 printf("%d\n",ans); 21 i++; 22 } 23 return 0; 24}

実行結果

入力
5 8 105
8 5 105
1 2 24
99 98 24
12 13 26
1 22 23
1 13 201
13 16 112

出力 ()内は税が変わる前の税抜き価格の最大値が表示されています.この中の値が正確に答えと一致しません.
(100) 107
(98) 102
(24) 24
(12) 22
(24) 26
(23) 27
(199) 224
(99) 114


#追記

現時点での問題点

大方の答えは一致するが,数値が小さい入力の際に答えより大きい結果が出てしまう場合がある.

再度書き直したコード

C

1#include<stdio.h> 2#include<math.h> 3int main(void){ 4 int a,b,c,ans; 5 int cal,ori; 6 int p1max,p2max; 7 int q1max,q2max; 8 int i,j; 9 while(1){ 10 scanf("%d %d %d",&a,&b,&c); 11 ans=0; 12 if(a==0&&b==0&&c==0) break; 13 for(i=1;i<=c;i++){ 14 p1max=(i*100+99)/(100+a); 15 p2max=((c-i)*100+99)/(100+a); 16 q1max=p1max*(100+b)/100; 17 q2max=p2max*(100+b)/100; 18 if(ans<(q1max+q2max)) ans=q1max+q2max; 19 } 20 printf("%d\n",ans); 21 } 22 return 0; 23}

*間違っている箇所を☆で表しました.

入力の一部

5 8 105
8 5 105
1 2 24
99 98 24
12 13 26
1 22 23
1 13 201
13 16 112
2 24 50
1 82 61
1 84 125
1 99 999
99 1 999
98 99 999
1 99 11   ☆
99 1 12
11 36 332
11 84 498

出力の一部

109
103
24
24
27
28
225
116
62
111
230
1972
508
1004
21
7
408
828

模範解答

109
103
24
24
26
27
225
116
62
111
230
1972
508
1004
20  ☆
7
408
828

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuma-s

2020/06/02 00:28

コンパイラは何ですか? VC++ のデフォルトのスタックサイズは 1Mバイトです。 int a[100000],b[100000],c[100000],ans; はそれを超えています。
grape_ll

2020/06/03 12:58

知識不足で申し訳ないのですが,コンパイラが何なのかはわかりません. 指定されたサイトで提出する形になっています. ですが,この配列の大きさは適当に決めたものなので入らないみたいですので小さくしようと思います. ご指摘ありがとうございました.
thkana

2020/06/03 23:36

そもそも配列にする必要は全くありません。 int a,b,c; として、 プログラム中の配列a[i],b[i],c[i]をすべてa,b,cに書き換えてもプログラムの結果に全く変化はありません。
guest

回答2

0

ベストアンサー

C言語で示すと私が解いたことになるのでPython言語で示します。計算はすべて整数で行うことができます。税率は小学生でも計算することができるので整数で計算することができます。

税込価格 = 税抜価格 + 税 = 税抜価格 + 税抜価格 × 税率(パーセント) ÷ 100

上記数式の÷というのが整数除算でありC言語でも/演算子で使うことができます。

税込価格から税抜価格を算出したとき、解の存在性と一意性が問題になります。証明するのが面倒なのでソースコードでは遅い計算を行っております。税抜価格から税込価格への計算は必ず解が存在し一意です。ここで税抜価格から税込価格を求める関数は単射ではあるが全射ではないので、税込価格から税込価格への計算においては一意ではあるが必ずしも解が存在しないという回答になるかと思います。

また、税抜価格の算出法は2分法を用いるか浮動小数点演算を用いることで高速化できるかと思います。余力があれば検討してみてください。

Python3

1# 税抜価格から税込価格を計算する関数 2# 3# [引数] 4# zeinuki : 税抜価格(整数) 5# zeiritsu : 税率(パーセント, 整数) 6# [返り値] 7# 税込価格(整数) 8def calcZeikomi(zeinuki, zeiritsu): 9 return zeinuki + zeinuki * zeiritsu // 100 10 11# 税込価格から税抜価格の最小値を探索する関数 12# 13# [考え方] 14# 税抜価格の最小値は1から税込価格の間にあり、1から探索すれば最小値が求まる 15# [引数] 16# zeikomi : 税込価格(整数) 17# zeiritsu : 税率(パーセント, 整数) 18# [返り値] 19# 税抜価格の最小値(整数)。存在しない場合はNone。 20def calcZeinukiMinimum(zeikomi, zeiritsu): 21 for i in range(1, zeikomi + 1): 22 if (calcZeikomi(i, zeiritsu) == zeikomi): 23 return i 24 return None 25 26# 税込価格から税抜価格の最大値を探索する関数 27# 28# [考え方] 29# 税抜価格の最大値は1から税込価格の間にあり、税込価格から探索すれば最大値が 30# 求まる 31# [引数] 32# zeikomi : 税込価格(整数) 33# zeiritsu : 税率(パーセント, 整数) 34# [返り値] 35# 税抜価格の最大値(整数)。存在しない場合はNone。 36def calcZeinukiMaximum(zeikomi, zeiritsu): 37 for i in range(zeikomi, 0, -1): 38 if (calcZeikomi(i, zeiritsu) == zeikomi): 39 return i 40 return None 41 42# 改定価格の最大値を計算する関数 43# 44# [引数] 45# rate0 : 変更前の消費税率(整数) 46# rate1 : 変更後の消費税率(整数) 47# price0 : 消費税率変更前の価格(整数) 48# [返り値] 49# 消費税率変更後の価格(整数)。存在しなければNone。 50def calcKaiteiMaximum(rate0, rate1, price0): 51 zeinuki = calcZeinukiMaximum(price0, rate0) 52 if (zeinuki == None): 53 return None 54 return calcZeikomi(zeinuki, rate1) 55 56# 問題を解く関数 57# 58# [考え方] 59# 2商品の合計価格が与えられるので、総当たり法を実施 60# [引数] 61# x : 変更前の消費税率(パーセント, 整数) 62# y : 変更後の消費税率(パーセント, 整数) 63# s : 消費税率変更前の2商品の税込合計価格 64def solve(x, y, s): 65 res = 0 66 for i in range(1, s): 67 price1 = calcKaiteiMaximum(x, y, i) 68 price2 = calcKaiteiMaximum(x, y, s - i) 69 if (price1 == None or price2 == None): 70 continue 71 res = max(res, price1 + price2) 72 return res 73 74# メインルーチン 75while (True): 76 ary = input().split() 77 x = int(ary[0]) 78 y = int(ary[1]) 79 s = int(ary[2]) 80 if (x == 0 and y == 0 and s == 0): 81 break 82 print(solve(x, y, s))

投稿2020/06/04 14:11

anndonut

総合スコア667

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

grape_ll

2020/06/07 07:48

目を付けるのが遅くなってしまい申し訳ございません. Pythonでの説明でも大変ありがたいです. 一度頂いたものを理解して自分で書いてみようと思います.
guest

0

以下の回答には誤りがありました。考え直してみますが、多分根っこのところで間違っていると思います。

プログラム以前の算数(一応代数が入るから数学か?)の問題が出来ていないから解けないのでは。
まず日本語で道筋を付けてから、プログラムに書き下すようにしたほうがよろしいかと思います。
「プログラミング言語で考える」なんてのは達人のワザなので、一般人は真似する必要はありません。

問題に

消費税率が x% のとき, 税抜価格が p 円である商品の税込価格は, p (100+x) / 100 円を小数点以下切り捨てたものである.

とあります。(この式をp*(1+x/100)で小数点以下切り捨て、と書かないところに出題者の優しさを感じます)
この式の性質として、
n*100 <= 分子 <= n*100+(100-1) (ただしnは整数)について同じ値になる
というのはわかりますね。とすると、税込み価格p1について、あり得る税抜価格の最大pmaxは
pmax=(p1*100+(100-1))/(100+x)(小数点以下切り捨て:つまり整数演算)
です。
であれば、税込み価格p1の商品の税率がx1からx2に変更になったとき、新税率でのあり得る価格の最大pnは
pn=pmax*(100+x2)/100(整数演算)
=(p1*100+(100-1))/(100+x1)*(100+x2)/100(整数演算)

2商品の旧税率においての合計額total1が与えられているのですから、
1つ目の商品価格p1を1~total1/2まで変化させて(当然もう一つの商品価格p2はtotal-p1)
新税率での商品価格の合計を求めて、それの最大を拾いだせばいい、わけです。

ここからがやっとプログラミングの出番。だけど、難しい話はないでしょう?

(いやまぁ、整数演算なんてプログラミングの世界以外ではほとんど使わない、というのはあるかも知れないけど)


以下追記。
プログラムに組む前に、上記
pmax=(p1100+(100-1))/(100+x)
pn=pmax
(100+x2)/100
の式について検証する。

ヒントの項にある
13 16 112 : 25, 75 : 29 + 87 = 116
より
13%税込計112円を
税抜25円/75円に分割した場合
16%税込で29円+87円で116円になることを確かめれば式は正しいと言えるだろう

検算の準備:
税抜25円 税率13%の税込み価格は
25*(100+13)/100=28

計算
p1=28円について税抜価格
pmax=(28100+(100-1))/(100+13)
=25 (ヒントの税抜と一致している)
新税率価格
pn=25
(100+16)/100
=29 (ヒントの新税率価格と一致している)...(1)
もう一つの商品について税抜価格
pmax=((112-28)100+(100-1))/(100+13)
=75 (ヒントの税抜と一致している)
新税率価格
pn=75
(100+16)/100
=87 (ヒントの新税率価格と一致している)...(2)

(1)+(2)は116でヒントと一致したので、計算方法は正しいと言えるだろう。

まだ不安があるなら、問題の先頭付近の

2商品の税抜価格 消費税率 5% 時の税込価格 消費税率 8% 時の税込価格

20, 80 21 + 84 = 105 21 + 86 = 107
2, 99 2 + 103 = 105 2 + 106 = 108
13, 88 13 + 92 = 105 14 + 95 = 109

のそれぞれ、あるいはヒントの他のデータについても検証してみればいい。

これで(やっと)プログラムの領分に持ち込めて、
p1=1,2,3,...56円について新税率での合計金額を求め、結果の金額が一番大きいものを示せばよい。いかにも「ループを使って最大値を求めろ」という問題に見える。配列は不要だと思うけど。ではプログラムを組みましょう。

...というのをあなた自身の計算式についてやってみて下さい。この時点で計算が合わないなら、プログラムに組んでも絶対に正答になりません。

投稿2020/05/30 23:30

編集2020/06/06 13:53
thkana

総合スコア7610

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

swordone

2020/05/31 02:44

> (いやまぁ、整数演算なんてプログラミングの世界以外ではほとんど使わない、というのはあるかも知れないけど) 要は小数点以下切り捨て、数学ではガウス関数とか床関数といった形でそこそこあると思いますよ。
grape_ll

2020/06/01 12:49

よく問題文を読まずに自分の中でp*(1+x/100)で小数点以下切り捨てと勝手に考えていたのが良くなかったみたいです. そこさえ直せば,後のことは書かせていただいたコードで出来ていると思うので解決できると思います. ご回答ありがとうございました.
grape_ll

2020/06/01 13:08

ご指摘いただいた通りに税抜き価格を計算したと思うのですが,最大の税抜き価格とはずれてしまいました. たとえば 5 8 105 の最大の税抜き価格は101になるはずなのですが,コードでやってみると100になってしまいます. おそらくは,合計価格に税をかけているのではなく,個別にかけたものを足しているからだと思うのですが,合計価格が分からないと変更後の税込み価格のようにループで確かめてみるというやり方が思いつきません.(というよりは実行時間が足らなくなってしまいそうです) お手数かとは思いますが,ご助言を頂けると幸いです. よろしくお願いいたします. コードは以下のように書きました. #include<stdio.h> #include<math.h> int main(void){ int a[100000],b[100000],c[100000],ans; int cal,ori; int i=0; while(1){ scanf("%d %d %d",&a[i],&b[i],&c[i]); ans=0; if(a[i]==0&&b[i]==0&&c[i]==0) break; int j; ori=(c[i]*100+99)/(100+a[i]); printf("(%d) ",ori); double postrate=1+(double)b[i]/100; for(j=1;j<ori;j++){ if(j==1) ans=j*(double)(1+b[i]/100)+(ori-j)*postrate; else if((cal=j*(double)(1+b[i]/100)+(ori-j)*postrate)<ans); else if((cal=j*(double)(1+b[i]/100)+(ori-j)*postrate)>ans) ans=cal; } printf("%d\n",ans); i++; } return 0; }
thkana

2020/06/01 22:27

「試してみたこと」は質問に追記(できれば書き換えではなく)して下さい。 計算そのものが根っこから間違っていたのに、以前の(間違った)プログラムをいじくることで解決しようとしていませんか? それこそ「プログラム言語で考えようとしている」の典型です。 ちゃんと日本語(と数式)で自分なりの計算過程を書来出して(面倒臭がらずにやってみて下さい)、その過程に従ってテストデータについて検証してみたうえで(出題者はとても親切で、最大になるときのパターンも示してくれています)、 それをプログラム言語に変換したならこんなことにはならないと思います。
grape_ll

2020/06/03 13:20 編集

質問内容に書くと回答者様にとって分かりづらいかと思い返信という形を取らさせていただいていたのですが,他の方々へのことも考えると追記の方が良いのかもしれませんね.次回からはそうするように心がけようと思います.ご指摘ありがとうございます。 また,追記を拝見させていただいたのですが,検証の例として出されている 13 16 112についてとなってい質問させていただきます. ”13%税込計112円を 税抜25円/75円に分割した場合 16%税込で29円+87円で116円になることを確かめれば式は正しいと言えるだろう” とおっしゃられていて,税変化前の税抜き価格の最大値が100前提として話を進められているのですが,お教えいただいた方法 =(c[i]*100+99)/(100+a[i]); で計算してみると99という値がでてしまい,この時点で話が進まなくなってしまいます.また,最初の税抜き価格の最大値が正確に求まれば変化後の税込み価格の最大値を求めるプログラムは初めからできていたので,一番の問題点を残したまま話が進んでいってしまいました. また,訂正して書かせていただいたプログラムは一度初めから書き直したものなのですが,具体的にどの部分が間違っているのかを教えていただけると幸いです. よろしくお願いいたします.
thkana

2020/06/04 00:22 編集

プログラミング関係ないです。さんすうきょうしつ、ですかね。 > 具体的にどの部分が間違っているのかを教えていただけると幸いです 教える必要がありますか? > 最初の税抜き価格の最大値が正確に求まれば変化後の税込み価格の最大値を求めるプログラムは初めからできていた ご自分で最初の税抜き価格の最大値の求め方が間違いだ、と言っていませんか? > 税変化前の税抜き価格の最大値 求めるべきは、税変化前の税抜価格の「合計」の最大値、です。 小数点以下切り捨てで 25*(100+13)/100=28 75*(100+13)/100=84 は計算できますね? 25+75=100, 28+84=112も納得しますね? 税込合計112円の場合の税抜合計100円というケースがあることは確認できました(100円は導かれるもので「前提」として導入したものではありません)。これを求められない、 > (c[i]*100+99)/(100+a[i]); で計算してみると99という値がでてしまい という式は間違っています。 単品ならそれでいいのですが、「合計」に対しては正しくありません。各項で小数点以下が切り捨てられるという状況下では、結合則 a*k+b*k=(a+b)*k は成り立ちません。
thkana

2020/06/04 00:42

今回の「旧税率での合計額が与えられている」という状況において、 税抜の合計価格を求めようという考え方がそもそも方針として適切でない、 というのが先に考えなければいけないことなのかも知れません。 とりあえず私の回答中では税抜の合計は求めていないはず。(途中で求まる材料は揃うけれど)
grape_ll

2020/06/04 01:19

訂正要請の箇所において,配列にしなくてもよいという部分は理解できました.確かに記憶しておく必要はないみたいです.ご指摘ありがとうございます. 私自身の経験として,何事においても勉強するうえで間違えた箇所に対しての反省をする必要があると考えていて,その具体的な箇所を指摘していただくことで後学の助けとなるのでぜひ教えていただきたいと考えております. 私が ”最初の税抜き価格の最大値が正確に求まれば変化後の税込み価格の最大値を求めるプログラムは初めからできていた” の部分で述べていたのは税変化後の話であり,税変化前が出来ていないということでしたが,長文ゆえ読解能力を要する文になってしまったようですね.こちらの配慮不足です.申し訳ございません. 式が間違っているとのご指摘についてなのですが,教えていただいたのは単品についての税抜き価格の式だったのですね.会話の流れからして二つの商品の式があの式で求まるという風に述べていると思ってしまっていました.確かによくよくみてみればこの式でそろうわけがないというのはすぐに理解できますね.なにも考えずに鵜呑みにしてしまい申し訳ございません. 税抜きを求める方針が正しくないとすると,今回の例でいえば 25,75をどうやって求めるのかが問題になると思います.この25,75が求められないうちは話が先に進まないと考えられます. また,この方針以外にはどのような方針が立てられますでしょうか. 私自身の考えとしては,必須になるのが 旧税率での税抜きの合計価格(新税率で最大になるために組み合わせを走査するため) の一点に絞っていたので他に具体的な方法が思い浮かばないです. よろしくお願いいたします.
thkana

2020/06/04 12:12

・旧税率での合計価格が与えられているのですから、 ・それを2つに分けて、 ・それぞれについて税抜を求め、新税率での価格を求めれば ・新税率での合計価格が求まります そんでもって、 ・旧税率での合計価格の分け方をいろいろ試して最大を探します なにか難しいかなぁ...
grape_ll

2020/06/04 13:42

教えていただいた方針におおよそ沿ってコードをかいてみました. するとある程度の大きさの数字の時は答えと一致して8割から9割がたは完成したと思います. しかし, 12 13 26 1 99 11 あたりの比較的小さい数では答えよりも1大きい数字が出てしまっています.切り捨ての部分が問題となっているのだろうというのは分かるのですが,20付近の数字でも一致しているものもあるので,どう対処するのが正しいのかが分かりません. 1 2 24 99 98 24 などでは一致しています.どのような工夫を加えればよいでしょうか. コードは質問内容に追記しておきます. よろしくお願いいたします.
swordone

2020/06/05 02:04

このコードだと、変更前の税込み価格が「11円と0円」のようなパターンが生まれてしまいませんか?
thkana

2020/06/05 11:23

この場合正答を求めるのに「工夫」は必要ではありません。題意を満たすプログラムにすればいいです(やっとプログラムの話ですね)。 求めている値段の組み合わせを確認してみて下さい。一方が0円では「2つの商品の合計」とは言えないでしょう。抱き合わせ、とかこじつけを言う場面でもないですし。 で、組み合わせをみたら気がついて欲しいのですけれど。 例えば旧税率での合計が10円だったときに、組み合わせとしては (1,9)(2,8),(3,7)(4,6)(5,5) だけ求めれば十分で、 (6,4)(7,3)(8,2)(9,1) の計算まで始めたらそれは無駄です。だって、(3,7)と(7,3)は「同じもの」ですから。もし、1つの計算に5分かかるようなケースだったら... 重複するケースを取り除く、というのはプログラムを作成するときに気をつけるべきこととして扱われることが多いですね。
anndonut

2020/06/05 19:03

もういっぽうの回答者のほうですけど、ソース直しました。要は税込価格から税抜価格の計算を安直にすなーってことですけど。 #include<stdio.h> #include<math.h> int zeinukiMuximum(int zeikomi, int zeiritsu) { double min1 = zeikomi * 100.0 / (100.0 + zeiritsu); double max1 = (zeikomi + 1.0) * 100.0 / (100.0 + zeiritsu); int min2 = (int)floor(min1); int max2 = (int)ceil(max1); int i; for (i = max2; i >= min2; i--) { if (i*(100+zeiritsu)/100 == zeikomi) return i; } return 0; } int main(void){ int x,y,s,ans; int p1max,p2max; int q1max,q2max; int i; while(1){ scanf("%d %d %d",&x,&y,&s); ans=0; if(x==0&&y==0&&s==0) break; for(i=1;i<s;i++){ p1max=zeinukiMuximum(i, x); p2max=zeinukiMuximum(s-i, x); if (p1max == 0 || p2max == 0) continue; q1max=p1max*(100+y)/100; q2max=p2max*(100+y)/100; if(ans<(q1max+q2max)) ans=q1max+q2max; } printf("%d\n",ans); } return 0; } あと総当り法で、対照だから後半いらないよねって考え、あんまり好きじゃないです。ソースが汚くなるので。実コードだとできるだけ無駄な計算はしないというのは作法としてあるのでしょうけど今回はただの学校の課題なのでそういう小賢しい最適化はいれたくないですね。
anndonut

2020/06/06 10:55 編集

問題の本質を見誤っていたみたいなので低評価を付けさせていただきました。私もですが。税込価格から税抜価格を算出するところが難しいです。あと回答者が質問者を見下しているところも気に入りませんでした。私も少しそういうところあったんですけどね。
thkana

2020/06/06 11:21

あなたの気に入るかどうかはどうしようもないですけど。 では、「問題の本質」とはなんだったのでしょう?
anndonut

2020/06/06 11:25

税抜価格から税込価格を計算するのは容易であるが税込価格から税抜価格を計算するのは容易ではないということです。これを計算するためには税抜価格の候補となる範囲を特定し探索する必要があります。単にforループをぶんまわせばいいわけですが。それがこの問題の本質です。
thkana

2020/06/06 11:28

ですから、プログラム以前にそこが分かっていないので「算数の問題」が延々と続いたわけですが?
anndonut

2020/06/06 11:33

いや、だから税抜価格から税込価格を計算するは算数の問題であるけど、税込価格から税抜価格を計算するのは高等数学の問題であると主張するわけです。アルゴリズムと整数論の範疇の問題であると認識しています。
thkana

2020/06/06 11:47

すみません、何を難しい話をしているのか私にはわかりません。 回答に書いたように至極簡単な話だと思うのですけれど。 (整数演算なんてプログラミングの世界以外ではほとんど使わない、とは思いました。回答に書いた通り) 難しさは置いておくとして、 回答の説明ではこの問題は解けない、間違った説明だということですか?
anndonut

2020/06/06 11:58

それではつまづきの半分しか解決できてないということです。手計算でやれば問題は解けると主張しますけど、私が実際に行ったのは概念のインクリメンタルなコード化です。テスト駆動開発といっても差し支えないと思います。関数を少しずつ組んでいくことで問題への糸口を探っていく方法です。貴殿はウォーターフォール型開発にこだわりがある、もしかしてUMLの専門家ですか?
thkana

2020/06/06 12:01

つまり、あなたの信奉する手法でないからダメだ、ということですね?
anndonut

2020/06/06 12:19

Zuishinさん、私が書いたC++とPython3のコード両方Acceptedでしたよ… Python3のほうは制限時間を意識していないので8秒かかりましたけど。
anndonut

2020/06/06 12:32

テスト駆動だからいいってわけじゃなくてウォーターフォールにも限界があるってことですよ。ちなみに私はテスト駆動開発よりもカーニハンのプログラミング作法のほうを信奉していますよ。つまり、最適化は、す、る、な、ってことです。
thkana

2020/06/06 13:14 編集

うん。WA。間違ってました...根本的に間違っていたことを理解しました。 もうしわけない。 修正って規模じゃないなぁ...
swordone

2020/06/06 14:00

そういえば、税込み価格で「ありえない金額」というのを思い出しました…。 税率8%のとき、端数切り捨てなら 112×1.08=120.96→120円 113×1.08=122.04→122円 となるので、「税込121円」というのが存在し得ません。
grape_ll

2020/06/07 07:56

事情が立て込んでしまい目を通すのが遅れてしまいました. 申し訳ございません. 一つ一つ確認させていただきます.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問