C++篮球错排问题 ——实质是求满足错排条件下的全排列
2010-07-03 21:04
274 查看
问题描述:
请编写程序求解篮球错排问题。已知n个篮子一字排开(n为用户输入的任意正整数),从左到右分别标着号:1,2,... ...,n;每个球也有编号,分别也是1,2,... ...,n。现要将这n个球全部放入这n个篮子中,满足:每个篮子放置1个球,球的号不能与其所在的篮子的号相同,且在相邻篮子内的球的球号不能相邻。例如,如果在相邻两个篮子内的球的球号分别为9和10,则是不允许的。请输出所有符合要求的放球方式(对于每种符合要求的放球方式,都应输出在每个篮子中的球号)。
程序:
下面的解法非常好理解,其实就是一边求全排列,一边判断当前生成的全排列是否满足错排条件,若满足就输出当前的排列……
==========
#include <iostream>
using namespace std;
static int COUNT=0;
//判断当前的排列a[]是否满足错排条件
bool validate(int a[],int size)
{
//第一个是否在第一个位置、或第一个和第二个是否相邻
if (a[0]==1||a[0]==a[1]+1||a[0]==a[1]-1)
return false;
//倒数第一个是否在倒数第一个位置、或倒数第一个和倒数第二个是否相邻
if (a[size-1]==size||a[size-1]==a[size-2]+1||a[size-1]==a[size-2]-1)
return false;
//中间的是否在对应的位置上、或与其前面和后面的位置上的是否相邻
for (int i = 2;i<=size-1;i++)
{
if (a[i-1]==i||a[i-1]==a[i-2]+1||a[i-1]==a[i-2]-1||
a[i-1]==a[i]+1||a[i-1]==a[i]-1)
return false;
}
return true;
}
//对于a[]的下标为k和m间的元素进行全排列,同时输出满足错排条件的的排列
void permuta(int a[],int k,int m,int NUM)
{
if(k == m)
{
if(validate(a,NUM)) //当前排列若满足错排条件就输出
{
COUNT++;
//打印结果
for(int k=0;k<NUM;k++)
cout<<a[k]<<" ";
cout<<endl;
}
}
else
{
for(int i=k;i<=m;i++)
{
swap(a[k],a[i]);
permuta(a,k+1,m,NUM);
swap(a[k],a[i]);
}
}
}
int main()
{
int NUM;
cout<<"Input NUM: ";
cin>>NUM;
int *per = new int[NUM];
for(int i=0;i<NUM;i++)
per[i] = i+1;
permuta(per,0,NUM-1,NUM);
cout<<endl<<"the total number is :"<<COUNT<<endl;
return 0;
}
请编写程序求解篮球错排问题。已知n个篮子一字排开(n为用户输入的任意正整数),从左到右分别标着号:1,2,... ...,n;每个球也有编号,分别也是1,2,... ...,n。现要将这n个球全部放入这n个篮子中,满足:每个篮子放置1个球,球的号不能与其所在的篮子的号相同,且在相邻篮子内的球的球号不能相邻。例如,如果在相邻两个篮子内的球的球号分别为9和10,则是不允许的。请输出所有符合要求的放球方式(对于每种符合要求的放球方式,都应输出在每个篮子中的球号)。
程序:
下面的解法非常好理解,其实就是一边求全排列,一边判断当前生成的全排列是否满足错排条件,若满足就输出当前的排列……
==========
#include <iostream>
using namespace std;
static int COUNT=0;
//判断当前的排列a[]是否满足错排条件
bool validate(int a[],int size)
{
//第一个是否在第一个位置、或第一个和第二个是否相邻
if (a[0]==1||a[0]==a[1]+1||a[0]==a[1]-1)
return false;
//倒数第一个是否在倒数第一个位置、或倒数第一个和倒数第二个是否相邻
if (a[size-1]==size||a[size-1]==a[size-2]+1||a[size-1]==a[size-2]-1)
return false;
//中间的是否在对应的位置上、或与其前面和后面的位置上的是否相邻
for (int i = 2;i<=size-1;i++)
{
if (a[i-1]==i||a[i-1]==a[i-2]+1||a[i-1]==a[i-2]-1||
a[i-1]==a[i]+1||a[i-1]==a[i]-1)
return false;
}
return true;
}
//对于a[]的下标为k和m间的元素进行全排列,同时输出满足错排条件的的排列
void permuta(int a[],int k,int m,int NUM)
{
if(k == m)
{
if(validate(a,NUM)) //当前排列若满足错排条件就输出
{
COUNT++;
//打印结果
for(int k=0;k<NUM;k++)
cout<<a[k]<<" ";
cout<<endl;
}
}
else
{
for(int i=k;i<=m;i++)
{
swap(a[k],a[i]);
permuta(a,k+1,m,NUM);
swap(a[k],a[i]);
}
}
}
int main()
{
int NUM;
cout<<"Input NUM: ";
cin>>NUM;
int *per = new int[NUM];
for(int i=0;i<NUM;i++)
per[i] = i+1;
permuta(per,0,NUM-1,NUM);
cout<<endl<<"the total number is :"<<COUNT<<endl;
return 0;
}
相关文章推荐
- 找出所有满足如下条件的六位数:它是一个完全平方数(即为某个整数的平方);该数同时也是回文数(即该数等于它的逆序数)。(C++上机考试题2)
- 对动态规划DP求解最优化问题的理解及应满足的条件
- C++ 两个有趣的问题(静态动态绑定,和类指针指向空的实质)
- 编程之美-快速寻找满足条件的2个数(扩展问题)的一个解法的注释
- C语言八皇后问题中怎样判断满足行列斜线没有棋子的条件?
- 编程之美2.12快速寻找满足条件的两个数及扩展问题Java版
- 问题五十三: 求满足条件n=a!+b!+c!的所有三位数n(a,b,c分别是n的百位十位个位)并输出,要求用自定义函数实现求阶乘。
- C++ 输出全排列 简单递归 N皇后问题
- 对动态规划DP求解最优化问题的理解及应满足的条件
- 加了限制条件的0-1背包问题(C++实现)
- C++基础系列:输入输出流条件状态问题
- HDU X问题 中国剩余定理--求满足条件的个数
- 对动态规划DP求解最优化问题的理解及应满足的条件
- C++笔试题 字符串的比较,全排列,类似 和分解的问题
- c++--------------条件编译的问题
- C++枚举算法之满足条件的整数
- 乱码问题!Eclipse 的控制台console必须用GBK编码。【转载】 Eclipse 的控制台必须用GBK编码。所以条件1和条件4必须同时满足否则运行的还是乱码。才能保证不是乱码。
- 对动态规划DP求解最优化问题的理解及应满足的条件
- C++:暴力搜索全排列解决背包问题
- 对动态规划DP求解最优化问题的理解及应满足的条件