我试图在HackerRank上解决这个问题几个小时。基本问题陈述如下:
你有一个只包含0和1的1D数组。你从第0个索引开始。 让我们假设数组的大小为n。如果你能超越数组的范围(即索引> n-1),你就赢了。但是你只能以两种方式行动:
另外,你只能登上价值为0的元素。 已知第0个索引处的值为0.(因此,您从有效位置开始)
'm'作为输入提供,它可以是0到100之间的任何值,包括0和100。 数组大小可以是2到100之间的任何值。
如果可以获胜,程序应打印“是”。否则“不”。
我尝试使用Java中的回溯算法来解决它。但它在大多数测试用例中都被拒绝了。
请帮帮我。提前谢谢。
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt();
int m=sc.nextInt();
int[] array = new int[n];
for(int i=0;i<n;i++){
array[i]=sc.nextInt();
}
if(m<2){
for(int i=0;i<n;i++){
if(array[i] == 1){
System.out.println("NO");
break;
}
}
System.out.println("YES");
}
else{
if(isSolvable(array,0,m,n))
{System.out.println("YES");}
else
{System.out.println("NO");}
}
}
static boolean isSolvable(int[] array,int x,int m,int n){
if(x>n-1){
//System.out.print(x + " ");
return true;
}
if(array[x] == 1) return false;
if(isSolvable(array,x+m,m,n)){
//System.out.print(x + " ");
return true;
}
if(isSolvable(array,x+1,m,n)){
//System.out.print(x + " ");
return true;
}
return false;
}
}
答案 0 :(得分:0)
编写这个游戏对于业余爱好者来说有点难,但可以解释我认为可以解决问题的算法。
首先,我认为你可以进行一步和“m”步骤的要点是这个问题的关键点。我的意思是你可以选择另一种方式。如果你达到它们3次,那么它们就没用了等等。我认为把它们放在一个阵列中是很重要的。
将数组定义为WellPoints
检查阵列的第一个点,您可以前进一步,“m”再进一步。将其另存为firstWellPoint
或WellPoints[0]
。
尝试使用简单的回溯算法通过一个或“m”步骤达到这一点。如果你不能,那就简单地说“不”。
如果您可以firstWellPoint
,请定义counter
以计算您访问的次数WellPoints
。
在检查每个点的后续步骤时,还要检查点是否适合一步并且m步两者。如果对于两者都进一步为“0”,则将其放置到WellPoints
数组。
现在,如果下次检查不成立,请返回WellPoints
数组的最后一个元素,并将counter
提高1。
当您找到新的WellPoint
时,请将counter
重置为1.
如果counter
= 3,则删除此WellPoint
并在此之前通过其他方式重新开始检查,这意味着WellPoint
数组的新最后一个元素。它可以通过检查counter
来确定方式,如果counter
= 1尝试一个步骤,当您再次来到这里时,这意味着如果counter
= 2尝试m步骤。
如果WellPoint
数组第一个元素,或者firstWellPoint
,如我所解释的那样,通过回溯WellPoint
数组3次再次到达,您也会删除此WellPoint
所以你的阵列将无法走到最后。
如果你到达阵列的末尾,那么你知道......
答案 1 :(得分:0)
我没有使用回溯,但只是递归,我能够解决问题并使所有测试用例都正确。您发布的代码也不会进行任何回溯。我也看到,在你的条件下,你错过了向后移动1的条件,这会导致你在某些情况下失败。
例如:0 1 1 1 0 0 1 1 1 0 1 1 1 1 0 1
,m = 5。
使用上面的示例,首先跳转到x + m,然后再次尝试x + m,然后尝试x + 1,否则就会离开。
打破这个测试用例:
0 1 1 1 0 0 1 1 1 0 1 1 1 1 0 1
^ x+m True
0 1 1 1 0 0 1 1 1 0 1 1 1 1 0 1
^ x+m False
0 1 1 1 0 0 1 1 1 0 1 1 1 1 0 1
^ x+1 False
0 1 1 1 0 0 1 1 1 0 1 1 1 1 0 1
^ x+1 False
使用您的代码,您将返回false而不是解决此问题,您需要执行以下操作:
0 1 1 1 0 0 1 1 1 0 1 1 1 1 0 1
^ x+m
0 1 1 1 0 0 1 1 1 0 1 1 1 1 0 1
^ x-1
0 1 1 1 0 0 1 1 1 0 1 1 1 1 0 1
^ x+m
然后又两个x + m来完成它以返回true。
要使用您的代码完成此操作,您需要添加条件以移回一个空格,但是这样做时,您可以合并无限递归循环例如:( - 1 + 1-1 + 1-1 + 1)这将导致stackoverflow。我建议包括的一件事是boolean
数组,用于记忆你以前见过的斑点。