夏洛克和野兽

时间:2015-11-08 01:30:45

标签: java

我在in this thread上解决了以下问题。无法继续前进,我搜索了这个问题并找到了这段代码:

public class Solution {

    public static void main(String[] args) {
        /* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
        Scanner in = new Scanner(System.in);
          int t = in.nextInt();
         while((t--)>0){
             int n = in.nextInt();
             StringBuffer answer = new StringBuffer();
            for(int j = 0;j <= n/5;j++){
                //System.out.println("J="+j+" N/5="+(n/5));
                //System.out.println("(n-5*j) = "+(n-5*j));
                 if((n-5*j)%3 == 0){
                    for(int k = 0;k< n-5*j;k++)
                         answer.append("5");
                     for(int k = 0;k < 5*j;k++)
                         answer.append("3");
                    System.out.println(answer.toString());
                     break;
                 }
            }
             if(answer.toString().equals(""))
                 System.out.println(-1);
         }
    }
}

我很难理解这段代码的工作原理;特别是(n-5*j)%3部分。有人可以帮我逐步理解吗?感谢。

2 个答案:

答案 0 :(得分:4)

要解决此问题,我们需要找到ab,以便:

- a + b = n
- a is divisible by 5 (a = 5*j where j is some integer)
- b is divisible by 3, (b = n-a = n-5*j is divisible by 3, written as (n-5*j)%3 == 0

答案是:(b times)5 followed by (a times)3

我们需要找到jn = 5*j + 3*something

如果我们找不到任何此类j,则问题无法解决。

如果有很多解决方案,最好的解决方案是提供最高b的解决方案,因为左边有五个以上的解决方案。但是,highest b表示最低j。因此,我们开始从0向上检查j

  for(int j = 0;j <= n/5;j++) // j cannot be > n/5, of course

一旦我们找到验证要求的j,我们就会完成,因为它必须是最好的(最低的j)。 j提供解决方案吗?那么让我们检查一下:

   if((n-5*j)%3 == 0) // if so, then j is a solution: b=n-5*j and a=5*j

    for(int k = 0;k< n-5*j;k++)
        answer.append("5"); // print 5 b times
    for(int k = 0;k < 5*j;k++)
        answer.append("3"); // print 3 a times

其余的代码用于解析输入并解决n的许多值,我认为它不需要解释。

答案 1 :(得分:1)

Scanner in = new Scanner(System.in);
int t = in.nextInt();

这里的代码非常自我解释。它创建新扫描程序并读取整数输入。

while((t--)>0){
         int n = in.nextInt();
         StringBuffer answer = new StringBuffer();

- 在while循环中说“嘿,如果我从t中减去一个,它还会大于零吗?如果是这样,继续!” - 表示减去一,类似于++表示加一。 int n只需要另一个扫描器输入,StringBuffer是用于创建最终解决方案输出的内容,通过添加到我们想要的任何内容。如果您知道StringBuilder是什么,它就类似于它。 Difference between StringBuilder and StringBuffer很好地解释了差异。

for(int j = 0;j <= n/5;j++){

此for循环在条件'j&lt; = n / 5'上运行。如果j小于或等于(&lt; =)整数n除以5,则它将在循环中运行代码。最后的j ++只是递增整数j,当循环首次运行时,整数j被声明为零。这是因为它并不总是评估为真并创建一个无限循环,因为那些是坏的。

if((n-5*j)%3 == 0){

此if语句执行操作'(n-5 * j)%3'然后比较结果是否等于零,如果是,则运行代码。由于操作的顺序,括号中的表达式将首先进行评估。 'n-5 * j'也遵循操作顺序,因此它不会评估一个人最初的想法。它将整数j乘以5乘以从n中减去乘积。结尾处的%表示将第一个数字除以下面的数字,然后返回余数。因此,3%3将返回0,因为3将3均匀分配为3. 62%3将返回2,因为3均匀分为60,最后两个是余数。

for(int k = 0;k< n-5*j;k++)
    answer.append("5");
for(int k = 0;k < 5*j;k++)
    answer.append("3");

这里的两个for循环非常相似,所以我只是解释它们中的第一个,你应该能够解释另一个。 类似于其他for循环(至少是循环的基本,循环的增强是不同的),for循环定义变量k并在开始时将其设置为零。它不会在每次迭代时创建k变量。

另外,你可能会说,“你怎么能在同一个班级中有两个k变量?”这是因为k变量是在封闭范围内定义的,这意味着只有循环内的代码才能访问k变量。所以,在循环之外你可以再次声明你想要的(作者所做的)。

表达式'k&lt; n-5 * j'几乎与我上面解释的表达式相同,只是没有%。在评估并运行满足条件后,它会增加k一次并在循环中运行代码,然后重新评估。

'answer.append( “5”);'将'5'追加到答案StringBuffer。它不会将其作为整数附加,它会附加为字符串/字符。无论StringBuffer的长度如何,它都会将其添加到字符串的末尾。

System.out.println(answer.toString());
break;

这将打印出答案StringBuilder的当前值。请注意,要将其打印出来,必须使用.toString()方法。 StringBuilder对象不是字符串,必须先将其转换为字符串,然后才能将其用作字符串。打印后,它会突破它所运行的最近的循环,因此它会突破:

for(int j = 0;j <= n/5;j++){}

到最后一点:

if(answer.toString().equals(""))
             System.out.println(-1);

这会将答案字符串构建器转换为字符串(如上所述),检查它是否为空(由于StringBuilders默认为空,因此不会附加任何内容)并且仅在打印时运行println。