C++篮球错排问题 ——实质是求满足错排条件下的全排列

问题描述:

 

请编写程序求解篮球错排问题。已知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;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值