ページ 1 / 1
Is it a Right Triangle? (AIZU ONLINE DUGE)の問題
Posted: 2011年7月16日(土) 01:37
by kerotan0820
今現在、こちらの問題をやっております
http://judge.u-aizu.ac.jp/onlinejudge/d ... 03&lang=jp
問題や、入力条件はリンク先に詳しく書いてありますので省略させていただきます。
プログラムは試行錯誤の上、このようになりました。
コード:
#include<stdio.h>
#include <stdlib.h>
main()
{
int *a,*b,*c,d,e;
scanf("%d",&d); //入力するデータセット数
/***********malloc関数で配列数を確保***********/
a = (int *)malloc(sizeof(int) * d);
b = (int *)malloc(sizeof(int) * d);
c = (int *)malloc(sizeof(int) * d);
if (a == NULL) exit(0);
if (b == NULL) exit(0);
if (c == NULL) exit(0);
/***********d個分のセットの値を入力************/
for(e=0;e<d;e++)
scanf("%d %d %d",&a[e],&b[e],&c[e]);
/**********************出力************************/
for(e=0;e<d;e++){
if( (a[e]*a[e]) + (b[e]*b[e]) == (c[e]*c[e]) )
printf("%s\n","YES");
else
printf("%s\n","NO");
}
}
最初、配列を a[10000] b[10000] c[10000] などと多めの配列をつくって、単純にforで入力のループと、出力のループを作ってみたのですが、ランタイムエラーなどと出力され、オンラインジャッジを通らなかったので、配列数を操作する方法が無いのか調べてみたところ、malloc関数というものを知り、挑戦してみました。
実行結果は、サイトのとおり、
3
4 3 5
4 3 6
8 8 8
この入力にたいして
YES
NO
NO
と出力されました。
データのセット数をなん十個に増やしても動作はしました…。
ですが、ジャッジを通りません…(汗;)
一体何が行けないのでしょうか
以前に、ジャッジをするのはPCだから、こういう記述は人間にしか理解できないから ~したほうが良い、といった感じのアドバイスを違う問題でうけたことがあるので、もしやそれと同じような事なのか…とも思っており、質問させていただきました。
学校の課題などでは有りませんので、解決を急いではおりません。
お時間のある方、大変お手数おかけしますが、ご協力いただけると幸いです。
Re: Is it a Right Triangle? (AIZU ONLINE DUGE)の問題
Posted: 2011年7月16日(土) 01:47
by kerotan0820
すみません。
printf("YES\n");
とすればいいものを
わざわざ %s で出力していたのは… 謎です(笑)
訂正しておきます^^;
Re: Is it a Right Triangle? (AIZU ONLINE DUGE)の問題
Posted: 2011年7月16日(土) 02:00
by ISLe
3つ目が斜辺に該当するとは限らないのでは?
例えば
5 4 3
は
YES
と出力されなければならない気がします。
Re: Is it a Right Triangle? (AIZU ONLINE DUGE)の問題
Posted: 2011年7月16日(土) 02:16
by kerotan0820
ISLe さんが書きました:3つ目が斜辺に該当するとは限らないのでは?
例えば
5 4 3
は
YES
と出力されなければならない気がします。
回答ありがとうございます。
コード:
#include<stdio.h>
#include <stdlib.h>
main()
{
int *a,*b,*c,d,e;
scanf("%d",&d); //入力するデータセット数
/***********malloc関数で配列数を確保***********/
a = (int *)malloc(sizeof(int) * d);
b = (int *)malloc(sizeof(int) * d);
c = (int *)malloc(sizeof(int) * d);
if (a == NULL) exit(0);
if (b == NULL) exit(0);
if (c == NULL) exit(0);
/***********d個分のセットの値を入力************/
for(e=0;e<d;e++)
scanf("%d %d %d",&a[e],&b[e],&c[e]);
/********************出力**********************/
for(e=0;e<d;e++){
if( (a[e]*a[e]) + (b[e]*b[e]) == (c[e]*c[e]) ||
(b[e]*b[e]) + (c[e]*c[e]) == (a[e]*a[e]) ||
(c[e]*c[e]) + (a[e]*a[e]) == (b[e]*b[e]))
printf("%s\n","YES");
else
printf("%s\n","NO");
}
}
これでもランタイムエラーが出ました;;
Re: Is it a Right Triangle? (AIZU ONLINE DUGE)の問題
Posted: 2011年7月16日(土) 05:21
by box
>1000 以下の3つの正の整数
この条件は、コードのどこに書いてあるのでしょうか?
Re: Is it a Right Triangle? (AIZU ONLINE DUGE)の問題
Posted: 2011年7月16日(土) 06:23
by a5ua
データセット数Nの上限が明示されていないので、Nが大きい場合に、
Memory Limit : 32768 KBという条件に引っかかっているのでしょう。
(3,000,000×4byte×3で約35000KBになります。)
ところで、このような入力データセットの場合、各行の入力に対して答えを出力すればいいので、
データセット分だけメモリを確保する必要はありません。
C言語で書くなら、以下のようなコードが雛形となるでしょう。
コード:
int main(void)
{
int i;
int n;
scanf("%d", &n);
for (i = 0; i < n; i++) {
/* 入力に必要な変数 */
// int a, b, c;など
/* 入力処理 */
// scanf("%d%d%d", &a, &b, &c);など
/* アルゴリズム */
}
return 0;
}
Re: Is it a Right Triangle? (AIZU ONLINE DUGE)の問題
Posted: 2011年7月16日(土) 13:40
by kerotan0820
box さんが書きました:>1000 以下の3つの正の整数
この条件は、コードのどこに書いてあるのでしょうか?
a5ua さんが書きました:データセット数Nの上限が明示されていないので、Nが大きい場合に、
Memory Limit : 32768 KBという条件に引っかかっているのでしょう。
(3,000,000×4byte×3で約35000KBになります。)
回答ありがとうございます。
成程…。 問題をきちんと読み取れてなかったみたいです。
偏の長さが1000以下、なのかと思っていました。
適切なプログラムを考えたいと思います。
a5ua さんが書きました:ところで、このような入力データセットの場合、各行の入力に対して答えを出力すればいいので、
データセット分だけメモリを確保する必要はありません。
入力 と 出力 をすべてまとめてしなくても良いということですか?
セットごとに出力するから、配列などを使う必要すら無い、ということですか?
Re: Is it a Right Triangle? (AIZU ONLINE DUGE)の問題
Posted: 2011年7月16日(土) 15:16
by box
kerotan0820 さんが書きました:
入力 と 出力 をすべてまとめてしなくても良いということですか?
セットごとに出力するから、配列などを使う必要すら無い、ということですか?
おそらくそうだと思います。
出題文に
>各データセットごとに、YES または NO を1行に出力して下さい。
と書いてあることから、
1)データセットを1行読む
2)YES/NOを1行出力する
を繰り返せばよい、と私は読み取りました。
Re: Is it a Right Triangle? (AIZU ONLINE DUGE)の問題
Posted: 2011年7月16日(土) 15:28
by たいちう
boxさんの書いた、↓について。
> >1000 以下の3つの正の整数
>
> この条件は、コードのどこに書いてあるのでしょうか?
この条件は入力データについての制限なので、
プログラムに記述する特別な必要はないです。
1000を超える整数が入力されたら"NO"と出力するというような仕様ではなく、
1000までの入力に対して正しく処理できれば良い、という意味です。
入力値が想定した範囲内にあるかどうかを気を付けることは大事なので、
入力エラーの処理を書くのは悪いことではないですけど。
> 入力 と 出力 をすべてまとめてしなくても良いということですか?
> セットごとに出力するから、配列などを使う必要すら無い、ということですか?
私もこの問題は解いてみましたが、1行入力して1行出力する処理を繰り返す
プログラムでOKでした。
Re: Is it a Right Triangle? (AIZU ONLINE DUGE)の問題
Posted: 2011年7月16日(土) 18:40
by ISLe
質問はランタイムエラーに関してだったのですね。
すみません。読み損ねてました。
EOFまで処理するように書けば、Nも読み捨てられますよね。
Re: Is it a Right Triangle? (AIZU ONLINE DUGE)の問題
Posted: 2011年7月17日(日) 02:49
by kerotan0820
以下のように訂正しました。
コード:
#include<stdio.h>
main()
{
int d,e;
scanf("%d",&d); //入力するデータセット数
for(e=0;e<d;e++){
int a=0,b=0,c=0;
scanf("%d %d %d",&a,&b,&c);
if( (a*a) + (b*b) == (c*c) ||
(b*b) + (c*c) == (a*a) ||
(c*c) + (a*a) == (b*b))
printf("YES\n");
else
printf("NO\n");
}
}
u-aizuの方は、何故か wait judge から変化がないので、変化があり次第通ったかは報告させていただきます。
回答ありがとうございます。
Re: Is it a Right Triangle? (AIZU ONLINE DUGE)の問題
Posted: 2011年7月17日(日) 14:00
by kerotan0820
ランタイムエラーでした;
EOFを使うのは、こういうことですか?
コード:
#include<stdio.h>
main()
{
int d,e;
if(scanf("%d",&d) != EOF){; //入力するデータセット数
for(e=0;e<d;e++){
int a=0,b=0,c=0;
if(scanf("%d %d %d",&a,&b,&c) == 3){
if( (a*a) + (b*b) == (c*c) ||
(b*b) + (c*c) == (a*a) ||
(c*c) + (a*a) == (b*b))
printf("YES\n");
else
printf("NO\n");
}
}
}
}
きちんと、三つのデータが入力されたか、調べるために
scanf("%d %d %d",&a,&b,&c) == 3 などと記述を以前にしたことが合った気がしたのでそれにも挑戦してみましたができませんでした…。
Re: Is it a Right Triangle? (AIZU ONLINE DUGE)の問題
Posted: 2011年7月17日(日) 14:36
by non
今回の課題ではEOFのことは考えなくていいと思いますが、学校の課題ではないので、いいますと・・・
>EOFまで処理するように書けば、Nも読み捨てられますよね。
データの個数がわからないときにEOFになるまで繰り返すという意味です。そうすれば、Nは読まなくてもいいということを
ISLe さんはたぶんいいたかったのでしょう。
したがって、 kerotan0820さんのEOFを使ったプログラムは意図が違います。
>ランタイムエラーでした;
どのプログラムがランタイムエラーなのでしょうか?
Re: Is it a Right Triangle? (AIZU ONLINE DUGE)の問題
Posted: 2011年7月17日(日) 15:44
by たいちう
AIZU ONLINE JUDGEは、サーバーが自動的にコンパイル・リンク・実行して、
採点してくれるのですが、少し気を付けるべきことがあるようです。
Volume0の問題で苦労をしているのならば、
Volume100の問題をやってみてはいかがでしょうか。
Re: Is it a Right Triangle? (AIZU ONLINE DUGE)の問題
Posted: 2011年7月17日(日) 16:36
by kerotan0820
nonさん>>
コード:
#include<stdio.h>
main()
{
int d,e;
scanf("%d",&d); //入力するデータセット数
for(e=0;e<d;e++){
int a=0,b=0,c=0;
scanf("%d %d %d",&a,&b,&c);
if( (a*a) + (b*b) == (c*c) ||
(b*b) + (c*c) == (a*a) ||
(c*c) + (a*a) == (b*b))
printf("YES\n");
else
printf("NO\n");
}
}
このプログラムがランタイムエラーでした。
たいちうさん>>
100の問題のほうが簡単だったのですね。
0 から始まるのだと勘違いしてました^^;
このプログラムの問題で問われていることを実行するプログラム自体は組めたので、これ以上先のことを考えるのは私にはまだ少し早いのかもしれません。
0からひと通りやってみたいと思います。
ということで、解決とはいえませんが、 100の簡単な問題から進めていきたいと思います。
Re: Is it a Right Triangle? (AIZU ONLINE DUGE)の問題
Posted: 2011年7月17日(日) 16:51
by たいちう
言語はCですか?それともC++ですか?
この掲示板に投稿するときもそうですが、
AIZU ONLINE JUDGEに投稿するときも、
言語を指定するようになっています。
意識できていますか?
また、Cの規格について詳しくないのですが、main()関数の戻り値が書かれていなく、
関数の最後のreturnもありません。どちらかというとコンパイルエラーや
警告になるような気がしますが、サーバーで採点する際にランタイムエラーと
評価されているのかもしれません。
もっと行儀良い無難なプログラムを書きましょう。
Re: Is it a Right Triangle? (AIZU ONLINE DUGE)の問題
Posted: 2011年7月17日(日) 17:49
by kerotan0820
たいちうさん>>
returun 0; でジャッジ通りました!
ありがとうございます。
これからはもっと丁寧に return なども欠かさずかくように意識付けます。