-5

私はここでICPCの質問をしていまし

問題は、* と . 1回の操作で行内の要素を切り替えることができるように、最初に正またはゼロになる行を切り替えました(行を2回切り替えると0の変化が得られます)*の変化は降順です。最後に、トグルが 1 つ残っている場合は、負の変化がある行の中で絶対値が最小の行をトグルします。

これが私のコードです - IDEONE.COMのコードの下にいくつかのテストケースがあります

import java.util.Scanner;


public class Main {

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int t = sc.nextInt();
    for (t = t; t > 0; t--) { 
      int n = sc.nextInt();
      int m = sc.nextInt();
      int k = sc.nextInt();
      char[][] array = new char[n][m] ;
      int[] tracker = new int[n];
      int[] trackerl = new int[n];
      int i,j;
      for (i = 0; i < n; i++) {
        String temp = sc.next();
        for (j = 0; j < m; j++) {             
          array[i][j] = (temp.charAt(j));  
        }   
      }
      int light = 0, diamond = 0;

      for (i = 0; i < n; i++) {
        for (j = 0; j < m; j++) {
          if (array[i][j] == '*') {
            diamond++;
          }     
        }
        tracker[i] = diamond;
        diamond = 0;
      }


      int a, b;
      int temp;
      int sortTheNumbers = n;

      for (a = 1; a < sortTheNumbers; a++) {
        for (b = 0; b < sortTheNumbers-a; b++) {
          if (tracker[b] > tracker[b + 1]) {
            temp = tracker[b];
            tracker[b] = tracker[b + 1];
            tracker[b + 1] = temp;
          }
        }
      }

      for (i = 0; i < n; i++)
        trackerl[i]=m-tracker[i];

      int br = 0;
      try {
        if (m % 2 == 0) {
          for ( i = 0; i <= n - 1; i++)
            if (tracker[i] > (m) / 2)
              br++;  
        }
        if (m % 2 !=0 ) {
          for (i = 0; i <= n - 1; i++)
            if (tracker[i] >= (m + 1) / 2)
              br++;
        }
      } catch (Exception e) {
      }

      int ans = 0;
      try {
        if (br >= k) {
          for (i = n - 1; i > (n - 1 - k); i--)
            ans += tracker[i];

          for (i = (n - 1 - k); i >= 0; i--)
            ans += trackerl[i];       
        }

        if (br < k) {
          if (br != 0 && br != n) {
            for (i = n - 1; i > (n - br); i--) {
              ans += tracker[i];
              k--;
            }

            int pass1 = 0, pass2 = 0;
            if (k % 2 == 0)
              pass1 = Math.max(tracker[(n - br)] + tracker[(n - br - 1)],
                                        trackerl[(n - br)] + trackerl[(n - br - 1)]);
              if (k % 2 != 0)
                pass2 = Math.max(tracker[(n - br)] + trackerl[(n - br - 1)],
                                          trackerl[(n - br)] + tracker[(n - br - 1)]);
                // System.out.print("Hp" + tracker[(n - br)]);
              }

              ans += Math.max(pass1, pass2);
              for (i = (n - 2 - br); i >= 0; i--)
                ans += trackerl[i];
              }
              if (br != 0 && br == n) {
                for (i = n - 1; i > (n - br); i--) {
                  ans += tracker[i];
                  k--;
                }
                if (k % 2 != 0) {
                  ans += tracker[(n - br)];
                }
                if (k % 2 == 0) {
                  ans += trackerl[(n - br)];
                }
                for (i = (n - 1 - br); i >= 0; i--) {
                  ans += trackerl[i];
                }        
              }
              if (br == 0) {
                if (k % 2 != 0) {
                  ans += tracker[(n - 1)];
                }
                if (k % 2 == 0) {
                  ans += trackerl[(n - 1)];
                }
                for (i = (n - 2); i >= 0; i--) {
                  ans += trackerl[i];
                }
              }
            }
          } catch (Exception e) {
          }
          System.out.println(""+ans);
        }
      }
    }

どのテスト ケースを選択しても、正しい答えが得られます。リンクからわかるように、テストケースの多様性を維持しましたが、それでもコードは正しくなく、審査員に受け入れられません。どこに欠陥があるのか​​ 本当にわかりません.それは私のコードですか、それとも私のロジックにありますか? 私のためにそれを指摘してください。

4

1 に答える 1

2

コードを書くことは、論文を書くことと同じです。文法、スペル、句読点、およびコードを読みやすくポイントを明確にするその他の規則があります。これら研究し、明確なコードを書くことは、あなたのコードを読む必要がある他の人だけでなく、あなた自身にとっても有益です (あなた自身のエラーがさらに増えるでしょう)。

コードをフォーマットするときに出くわしたいくつかの項目を指摘します。(例はメモリからのものであり、コードではありません)

if(x=3;y>(2-2-x);y++) 

このような行を書かないでください。

  1. ifは関数ではなく、「if (」ではなく「if(」を選択すると、もう少し関数のように見えます。同じことがキーワードwhileにも当てはまります。

  2. 算術演算の複数の文字列 (特に「+」と「-」) を長い行に入れると (「(2-2-x)」のように)、「-」文字が果たすことができる二重の役割が混乱します。スペース「(2 - 2 - x)」を入れて、単項否定演算 (負の数) なしで複数の減算を扱っていることを読者に認識させます。

  3. ifステートメントには 3 つのパラメーターが必要です (セミコロンで区切られます)。各パラメーターの後にスペースを入れると、それらが「次の」パラメーターにあることをリーダーに知らせることができます。「if (x=3; y>(2-2-x); y++)」よりも「if (x=3; y>(2-2-x); y++)」を優先します。

続きの例では

if(x=3;y>(2-2-x);y++) 
  {x=3;y=2;}

次の行の括弧は、読解の問題を引き起こします。

  1. これらは、if ステートメントの後に角かっこがない場合と同じフォーマットの問題が発生する可能性があります。ブロック全体を 1 行に配置すると、ブロックと行を混同し、行の並べ替えがプログラムの動作に劇的な影響を与えます。これは悪いです。これを修正するには、"if (x = 3; y >(2 - 2 - x); y++) {" を優先します。

  2. その上にある if ステートメントの書式設定を模倣する複合ステートメントが 1 行にあり、読者を混乱させて、これが後続のネストされた if ステートメントの一部であると信じ込ませる可能性があります。2 つの割り当てステートメントをそれぞれ別の行に置くと、はるかに読みやすくなります。

  3. ブロックの終わりをステートメントに結び付けます。これにより、ブロックの境界が特定の操作に結び付けられます。多くの場合、コードを更新する必要があり、ステートメントとブロックの終わりがプログラムの存続期間にわたって接続される可能性はわずかです。ブロック区切り文字の終わりを非ステートメント行に配置することを好みます。

上記のすべてのポイントを一緒に使用すると、次のようなコードになります。

if (x = 3; y > (2 - 2 - x); y++) {
  x = 2;
  y = 3;
}

簡単な書式設定の後、「もしこれなら、それなら」という複数のブロックがあることは明らかです。これらのブロックの多くは、「これならあれ、これでなければあれ」というパターンに従うことも明らかです。この言語には、前の if ブロックに接続された「else」ブロックを使用して、このようなパターンを処理する機能が組み込まれています。

(あなたのコードから直接例)

        if (k % 2 != 0) {
          ans += tracker[(n - 1)]
        }
        if (k % 2 == 0) {
          ans += trackerl[(n - 1)];
        }

はるかにきれいに書くことができます

        if (k % 2 != 0) {
          ans += tracker[(n - 1)]
        } else {
          ans += trackerl[(n - 1)];
        }

または、並べ替えを使用して不等式よりも等式を強調する

        if (k % 2 == 0) {
          ans += tracker1[(n - 1)]
        } else {
          ans += tracker[(n - 1)];
        }

続けることもできますが、このような変更を行った後は、実際にはコードがはるかに良い場所から開始されるため、基本的ないくつかの作業が完了するまで、コードを読みやすくするための高レベルの手法について話すことは意味がありません。それでも、変数の目的を説明するために、変数名には完全な単語を使用することをお勧めします。

幸運なことに、私の再フォーマットで、閉じブロック区切り文字を切り取った可能性があります (それらは一致しません) か、そもそもそこになかった可能性があります (フォーマットされていないバージョンをチェックインすることはできませんでした)。

于 2013-01-12T12:40:40.413 に答える