卡拉茲(Callatz)猜想已經在1001中給出了描述。在這個題目里,情況稍微有些復雜。
當我們驗證卡拉茲猜想的時候,為了避免重復計算,可以記錄下遞推過程中遇到的每一個數。例如對?n=3?進行驗證的時候,我們需要計算 3、5、8、4、2、1,則當我們對?n=5、8、4、2 進行驗證的時候,就可以直接判定卡拉茲猜想的真偽,而不需要重復計算,因為這 4 個數已經在驗證3的時候遇到過了,我們稱 5、8、4、2 是被 3“覆蓋”的數。我們稱一個數列中的某個數?n?為“關鍵數”,如果?n?不能被數列中的其他數字所覆蓋。
現在給定一系列待驗證的數字,我們只需要驗證其中的幾個關鍵數,就可以不必再重復驗證余下的數字。你的任務就是找出這些關鍵數字,并按從大到小的順序輸出它們。
輸入格式:
每個測試輸入包含 1 個測試用例,第 1 行給出一個正整數?K?(
輸出格式:
每個測試用例的輸出占一行,按從大到小的順序輸出關鍵數字。數字間用 1 個空格隔開,但一行中最后一個數字后沒有空格。
輸入樣例:
6
3 5 6 7 8 11
輸出樣例:
7 6
思路:最開始就順著想,要求出所有輸入數字的猜想數;如果輸入的K個數字有數字n不在所有的猜想數內,那n就是其中一個關鍵字;
1.輸入數字歸為一個數組a[]2.求出所有猜想數,歸為一個數組b[]
3.如果輸入的數字a[i]在數組b[]中,那a[i]歸零
4.最后對a[]排序,按格式輸出答案
因為猜想數的個數是動態的,必然是有重復的;所以需要考驗數組長度,或去重,這樣能加快一些效率;(之前錯誤的思路:1.求出所有輸入數字的關鍵字(也就是第一步運算得出的數字),放入一個數組內keyNum[],
2.用輸入的數字數組inputNum[]與keyNum[]中的值比較,相等則為零3.最后輸出inputNum[]
錯誤的地方在于,inputNum[]中的元素,可能不再關鍵字keyNum[]中,而在所有的猜想數字中
)以下為笨方法,直接定義了一個長度為10000的猜想數數組;
import java.util.Scanner;
public class Main{
public static void main (String [] args){
Scanner in =new Scanner(System.in);
int num =in.nextInt();
int []testNum=new int[num];//聲明輸入數字的數組
int []result=new int[10000];//聲明猜想數字的數組
int count=0;
for(int i=0;i
{
testNum[i]=in.nextInt();
}
result=myMethod(testNum);//獲得所有猜想數字
for(int i=0;i
{
for(int j=0;j<10000;j++)
{
if(result[j]==testNum[i])
{
testNum[i]=0;
break;
}
}
}
for(int i=0;i
{
boolean tempBool=true;
for(int j=0;j
{
if(testNum[j]
{
int[]temp= {testNum[j]};
testNum[j]=testNum[j+1];
testNum[j+1]=temp[0];
tempBool=false;
}
}
if(tempBool)
{
break;
}
}
for(int i:testNum)//輸出答案
{
if(i!=0&&count==0)
{
System.out.print(i);
count++;
}
else if(i!=0&&count>0)
{
System.out.print(" "+i);
}
}
}
public static int[] myMethod(int[]testNum)//求所有猜想數字的方法
{
int[]temp=new int[10000];
int tempCount=0;
for(int i =0;i
{
int m=testNum[i];
for(int j=0;j
{
if(m%2==0)
{
temp[tempCount]=m/2;
m=m/2;
tempCount++;
}
else
{
temp[tempCount]=(3*m+1)/2;
m=(3*m+1)/2;
tempCount++;
}
}
}
return temp;
}
}