-5

我在这里遇到了一个 ICPC 问题

问题归结为找到最大值。可以通过在具有 * 和 的矩阵中进行 K 操作来实现。这样我们就可以在一次操作中切换一行中的元素。我首先切换了导致正数或零的行(切换行 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语句需要三个参数(用分号分隔)。在每个参数之后放置空格可以向读者表明它们在“下一个”参数中。支持“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 语句后没有括号相同的格式问题。通过将整个块放在一行上,您会混淆块和行,并且任何行重新排序都会极大地影响程序的运行。这是不好的。要解决此问题,请支持“if (x = 3; y >(2 - 2 - x); y++) {”。

  2. 单行上有一个复合语句,它模仿了它上面的 if 语句的格式,这可能会使读者误以为这是后续嵌套 if 语句的一部分。将两个赋值语句放在各自的行上更具可读性。

  3. 您将块的末尾绑定到一个语句,该语句将块边界与特定操作耦合。通常需要更新他们的代码,并且语句和块的结尾应该在程序的生命周期内连接的可能性很小。倾向于将块分隔符的结尾放在非语句行上。

上述所有要点一起使用时,代码看起来像

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

经过一些简单的格式化后,很明显你有多个“如果这个,那么那个”块。很明显,这些块中的很多都遵循一种模式,“如果这样,那就那样。如果不是这样,那就那样”。该语言具有处理这种模式的内置能力,其中“else”块附加到先前的 if 块。

(直接来自您的代码的示例)

        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 回答