(一) 問題描述:
/**
* 請編寫程式求解籃球錯排問題。
* 已知n個籃子一字排開(n為使用者輸入的任意正整數),從左至右分別標著號:1,2,... ...,n;每個球也有編號,分別也是1,2,... ...,n。
* 現要將這n個球全部放入這n個籃子中,滿足:每個籃子放置1個球,球的號不能與其所在的籃子的號相同,且在相鄰籃子內的球的球號不能相鄰。
* 例如,如果在相鄰兩個籃子內的球的球號分別為9和10,則是不允許的。請輸出所有符合要求的放球方式(對於每種符合要求的放球方式,都應輸出在每個籃子中的球號)。
*/
(二) 來源程式
#include <iostream>
using namespace std;
const int size = 10; //存放球的個數
int ball[size]; //存放球
int basket[size]; //存放籃子
int count = 0; //解得個數
void checkAndDisply();
void rotate(int newsize);
void display();
void basketSort(int n);
void checkResult();
//迴圈右移
void rotate(int newsize)
{
int position = size-newsize;
int temp = ball[position];
for(int i=position+1;i<size;i++)
ball[i-1] = ball[i];
ball[size-1] = temp;
}
//輸出結果
void display()
{
count++;
cout<<"第"<<count<<"種方式是:"<<'/t';
for(int i=1;i<=size;i++)
cout<<"籃子"<<i<<"中的籃球號是:"<<basket[i-1]<<'/t';
cout<<endl;
}
//將球進行全排列,並同時檢驗錯排的情況
void basketSort(int n)
{
if(size==1)
return ;
else
{
for(int j=0;j<n;j++)
{
basketSort(n-1);
if(n==2)
checkAndDisply();
rotate(n); //
}
}
}
//檢驗解得合法性
void checkAndDisply()
{
for(int i=0;i<size;i++)
basket[i] = ball[i];
for(int j=0;j<size;j++)
{
if(basket[j]==j+1) //球的編號不能和籃子的編號相同
break;
if(j!=0)
//相鄰籃子內的球的球號不能相鄰
if(basket[j]-basket[j-1]==1||basket[j]-basket[j-1]==-1)
break;
}
if(j==size) //得到一組解,顯示出來
display();
}
void checkResult()
{
if(count==0)
cout<<"問題無解!"<<endl;
}
int main()
{
//產生球的數組
for(int i=0;i<size;i++)
ball[i] = i+1;
basketSort(size);
checkResult();
return 0;
}
==============================================
換種寫法寫成可以動態更改要進行錯排的球的數目,如下:
#include <iostream>
using namespace std;
void checkAndDisply(int N,int &count,int* ball,int* basket);
void rotate(int N,int newsize,int* ball);
void display(int N,int &count,int* basket);
void basketSort(int N,int n,int& count,int* ball,int* basket);
int main()
{
int n;
cout<<"Input Ball Number:";
cin>>n;
int *ball = new int[n]; //數組ball存放球
int *basket = new int[n]; //數組basket存放籃子的
int count = 0; //解的個數
for(int i=0;i<n;i++)
ball[i] = i+1;
basketSort(n,n,count,ball,basket);
if(count == 0)
cout<<"問題無解!"<<endl;
return 0;
}
//迴圈右移
void rotate(int N,int newsize,int* ball)
{
int position = N-newsize;
int temp = ball[position];
for(int i=position+1;i<N;i++)
ball[i-1] = ball[i];
ball[N-1] = temp;
}
//將球進行全排列,並同時檢驗錯排的情況
void basketSort(int N,int n,int& count,int* ball,int* basket)
{
if(N==1)
return ;
else
{
for(int j=0;j<n;j++)
{
basketSort(N,n-1,count,ball,basket);
if(n==2)
checkAndDisply(N,count,ball,basket);
rotate(N,n,ball);
}
}
}
//檢驗解得合法性
void checkAndDisply(int N,int &count,int* ball,int* basket)
{
for(int i=0;i<N;i++)
basket[i] = ball[i];
int j;
for(j=0;j<N;j++)
{
if(basket[j]==j+1) //球的編號不能和籃子的編號相同
break;
if(j!=0)
//相鄰籃子內的球的球號不能相鄰
if(basket[j]-basket[j-1]==1||basket[j]-basket[j-1]==-1)
break;
}
if(j==N) //得到一組解,顯示出來
display(N,count,basket);
}
//輸出結果
void display(int N,int &count,int* basket)
{
count++;
cout<<"第"<<count<<"種方式是:"<<'/t';
for(int i=1;i<=N;i++)
cout<<"籃子"<<i<<"中的籃球號是:"<<basket[i-1]<<'/t';
cout<<endl;
}