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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

アルゴリズム

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

Q&A

解決済

3回答

1769閲覧

0と1が入力される多次元配列の1を囲う棒の数え方

kinako_make

総合スコア7

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

アルゴリズム

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

0グッド

0クリップ

投稿2020/09/25 01:03

編集2020/09/25 06:23

スクールの課題です。

1、多次元配列の広さを入力
例:4 4
2、指定された広さ分の情報の入力
例:1
4 4
0010
1110
0010
0010

例:2
3 5
00010
11001
01100

3、1を囲うのに必要な棒が何本必要か計算して出力
例:1は14本
例:2は18本

現在の考え方
1を囲うのに4本必要 - 重なっている分(1つの場所で2本) = 必要な本数
例で考えると
(4×6)- (5×2)= 24 - 10 = 14
(4×6)- (3×2)= 24 - 6 = 18
で求められるとわかりました。

しかし、途中でどうやってプログラミングをすればいいのかわからなくなってしまいました。
ループの中で要素数が一致するのを数えようと思ったのですが…timelimit exceededになりました。

import

1 2 3public class Main { 4 5 public static void main(String[] args) { 6 Scanner sc = new Scanner(System.in); 7 8 int heigt = sc.nextInt(); //高さを取得 9 int width = sc.nextInt(); //幅を取得h); 10 11 //情報を1文字ずつ配列に格納していく 12 String[][] flower = new String[heigt][width]; 13 int count = 0; //#の数を数える 14 for (int i = 0; i < heigt; i++ ){ 15 String str = sc.next(); 16 for (int j = 0; j < width; j++ ){ 17 char[] arrayC = str.toCharArray(); //1文字ずつに変換 18 Character tmp = arrayC[j]; 19 flower[i][j] = tmp.toString(); 20 if("#".equals(flower[i][j])){ 21 //#の数を数える 22 count++; 23 } 24 } 25 } 26 System.out.println(count); 27 int count2 = 0; //#の縦の要素数が一緒がいくつあるか 28 int count3 = 0; //#が連続で続いているか 29 int[][] flg = new int[heigt][width]; //#があるか確認したら1にする 30 int idx = 0; 31 for (int i = 0; i < heigt; ){ 32 for (int j = 0; j < width; j++ ){ 33 if(flg[i][j] == 0 && "#".equals(flower[i][j])){ 34 //#の位置の要素数を保存 35 idx = j; 36 flg[i][j] = 1; 37 }else{ 38 //#がなければflgをあげる(確認済) 39 flg[i][j] = 1; 40 } 41 } 42 if(i > 0){ 43 for (int k = 0; k < width; k++ ){ 44 if("#".equals(flower[i][k]) && idx == k){ 45 //# かつ 前のと同じ位置の場合カウントする 46 count2++; 47 } 48 } 49 } 50 } 51 System.out.println(count2); 52 } 53} 54コード

間違っている点や
他の考え方など、ご教授いただければと思います。
よろしくお願いいたします。

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

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

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

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

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

Zuishin

2020/09/25 01:26

なぜ 14 本と 18 本になるのかどうしてもわかりません。これは正しい答えですか? 棒を 2 で表すと、次のようになるのではないですか? 00020 02212 21112 02212 00212 00020
kinako_make

2020/09/25 01:37

図のようであっていますが、角の部分が2本必要なので「2」の数と異なります。 111 021 上記のように「2」で表すと1つですが、実際の棒は「2」の上と右側に必要なので2つとして数えます。 わかりにくくて、すみませんがこの説明で理解できますでしょうか。
Daregada

2020/09/25 01:40 編集

(説明不足なんですが)おそらく、縦と横を囲む棒を別に考えるのではないかと。 _|1 1 1 みたいに。って書いている間に補足があったわ。 問題2は、4行目が記述漏れの可能性がある。
Zuishin

2020/09/25 01:39

なるほど。「棒」の意味がわかりました。
Zuishin

2020/09/25 01:47

アルゴリズムとしては、まず 1 の数を数えてそれを 4 倍し、一つ一つの 1 を見て隣接する 1 の数を引けばいいと思います。多分質問に書いてあるのと同じですね。 この場合、 0010 1110 0010 0010 これをまず 000000 000100 011100 000100 000100 000000 このように変換すると、1 の隣に 1 か 0 があることが保証されるので、アルゴリズムが単純になると思います。その上で隣接した 1 の数を数えて次のように変換します。 000000 000100 012300 000200 000100 000000 そうすると引く数は 1 + 1 + 2 + 3 + 2 + 1 = 10 になるので、6 * 4 - 10 = 14 が出ます。
yureighost

2020/09/25 01:49

これでもいまいちよくわかりませんね。 000 010 000 これで周囲囲むのに4本いるというのはわかりましたが、 000 011 000 こうだとすると棒が共有されてるのは1本で7本必要になるのではないのですかね。
momon-ga

2020/09/25 05:38 編集

例2は、重なってるのが4か所だと思いますが、なぜ3? あ、例が、修正された。
Zuishin

2020/09/25 01:56

yureighost さん、1 を囲む棒、つまり 1 の塊と外界を分けるボーダーだと思うので、1 と 1 の間に棒はないと思います。
yureighost

2020/09/25 02:07

Zuishinさん あ、なるほど、1同士の間には棒はいらないってことですか。
fana

2020/09/25 04:43

「重なっている分」を引く みたいな変に工夫した(?)考え方をせずとも, 単純にカウントしていけばよい,すなわち, 「棒を置ける箇所すべてに関して,そこに棒を置くかどうかを判断すればいい」と考えたらどうですか. 行き着く結果(隣接要素の値が異なる箇所の個数を数えるだけの話になる)は一緒でしょうが,「考え方」として.)
guest

回答3

0

ベストアンサー

特に気の利いたアルゴリズムは使っていない単純な解法です。
現在処理している座標が'1'の場合に棒に4加算し、
更に左と上それぞれの座標をチェックしてそこが'1'なら棒を2本減算します。

java

1public static void main(String[] args) { 2 Scanner sc = new Scanner(System.in); 3 4 int heigt = sc.nextInt(); //高さを取得 5 int width = sc.nextInt(); //幅を取得h); 6 // 高さ・幅入力の改行入力を捨てる 7 sc.nextLine(); 8 9 //花壇の情報を1文字ずつ配列に格納していく 10 char[][] flower = new char[heigt][width]; 11 for (int i = 0; i < heigt; i++){ 12 flower[i] = sc.nextLine().toCharArray(); 13 } 14 15 // 棒の数 16 int barCnt = 0; 17 for (int i = 0; i < flower.length; i++) { 18 char[] cs = flower[i]; 19 for (int j = 0; j < cs.length; j++) { 20 char c = cs[j]; 21 // 現在座標が'1'の場合 22 if (c == '1') { 23 // 棒の数に4本加算する 24 barCnt += 4; 25 // 上座標が'1'の場合 26 if (i > 0 && flower[i - 1][j] == '1') { 27 // 棒の数から2本減算する 28 barCnt -= 2; 29 } 30 // 左座標が'1'の場合 31 if (j > 0 && cs[j -1] == '1') { 32 // 棒の数から2本減算する 33 barCnt -= 2; 34 } 35 } 36 } 37 } 38 System.out.println("棒の数:" + barCnt); 39 sc.close(); 40}

投稿2020/09/25 02:54

yureighost

総合スコア2183

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

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

kinako_make

2020/09/25 04:04

ありがとうございます。 トレースして、ゆっくり考えてみます。
kinako_make

2020/09/25 06:44

やっと理解できました! char型配列が全然わかっていなかったことがわかりました。(多次元配列含め) 条件式も私がやりたかったことそのものでした。 自分ではどうやって条件式を書けばいいかわからなっかので(多次元配列の理解ができてなかったので) とても勉強になりました。 ありがとうございました!
guest

0

類似の問題で、「島がいくつあるのか」という問題があります。
1を陸地、0を海に見立て、陸続きの島がいくつ存在するかを数える問題です。
この問題の場合、代表的な解法として、ある陸地から隣接する地形を幅優先探索で、訪問済みのフラグを立てながら陸続きを調べる、というものがあります。
このとき、陸地から海または盤外に出ようとする回数を数えれば、それがすなわち必要な棒の数ということになります。

投稿2020/09/25 05:35

swordone

総合スコア20669

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

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

kinako_make

2020/09/25 06:20

そのような似た問題もあるのですね。 とても考え方の参考になりました。 ありがとうございます。
guest

0

ロジックは、すでに回答済みなので、以下について

ループの中で要素数が一致するのを数えようと思ったのですが…timelimit exceededになりました。

実際に自分で動かしてみた方がよいです。
または、動かしたあとに修正したなら再実行して動作確認することをオススメします。

iがカウントアップされないので、無限ループですね。

java

1 for (int i = 0; i < heigt; ){ 2 for (int j = 0; j < width; j++ ){ 3 if(flg[i][j] == 0 && "#".equals(flower[i][j])){

投稿2020/09/25 05:34

momon-ga

総合スコア4826

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

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

kinako_make

2020/09/25 06:22

本当ですね。 なんでそこだけ抜けたのかわかりませんが、思い込みで気づけませんでした。 ご指摘ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問