算法描述
某人給6個朋友每個人都寫了一封信,同時寫了這6個朋友地址的信封,有多少種投放信箋的方法,使得每封信與信封上的收信人都不相符?
算法思路
-
6封信可能出現的結果:
-
所有的信都是在對應的信封中,也就是所有的信都放對了信封,這種情況只有一種
-
部分信放錯了信封
-
全部信都放錯了信封
-
-
題目要求的就是求最后一種情況,也就是全部新都放錯了信封
-
定義一個數組
a[i]
,a[1] = 1
表示第一封信放在了第一個信封中 -
限制條件
-
a[i]!=i
即限制信放在正確的信封中 -
a[i]!=a[j]
即限制信不能放在同一個信封
-
-
回溯條件
a[i]=6
即已經遍歷到了最后一封信
算法實現
System.out.println("輸入n:");
Scanner scaner = new Scanner(System.in);
int n = scaner.nextInt();
scaner.close();
int s = 0;//解的個數統計
int[] a = new int[n+1];
a[1]=2;
int i=1;
while(true){
boolean flag = true;
if(a[i]!=i){
for(int j=1;j<i;j++){
if(a[j]==a[i]){
flag = false;
break;
}
}
}else{
flag = false;
}
if(flag&&i==n){
s++;
for(int j=1;j<=n;j++){
System.out.print(a[j]);
}
System.out.print(" ");
//出現十個解換行
if(s%10==0){
System.out.println("");
}
}
if(flag&&i<n){
i++;
a[i]=1;
continue;
}
while(a[i]==n&&i>0){
i--;//回溯,a[i]到末尾,則回溯
}
if(i>0){
a[i]++;//向后移
}else{
break;
}
}
System.out.println("\n"+"s="+s);