我在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
部分。有人可以帮我逐步理解吗?感谢。
答案 0 :(得分:4)
要解决此问题,我们需要找到a
和b
,以便:
- 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
我们需要找到j
,n = 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。