分书和八皇后问题

1.分数问题:若干个人如何都拿到自己喜欢的书

#include<iostream>
#include<iomanip>
using namespace std;
int Num;  //方案数
int take[5];  //5本书分别给谁(用户编号)
bool assigned[5];  //5本书是否已分配
int like[5][5]={{0,0,1,1,0},{1,1,0,0,1},{0,1,1,0,1},{0,0,0,1,0},{0,1,0,0,1}};
void Try(int id)
{
    //递归终止条件:所有的读者都已分配到合适的书籍
    if(id==5)
    {
        //方案数加1
        Num++;
        //输出方案细节
        cout<<"第"<<Num<<"个方案(按ABCDE次序):";
        int i;
        for(i=0;i<5;i++)
            cout<<take[i]<<" ";
        cout<<endl;
        return;
    }
    //逐一为每本书找到合适的对着
    int book;
    for(book=0;book<=4;book++)
    {
        //是否满足分书条件
        if((like[id][book]==1) && !assigned[book])
        {
            //记录当前这本书的分配情况
            take[id]=book;
            assigned[book]=true;
            //为下一位读者分配适合书籍
            Try(id+1);
            //将书退还(回溯),尝试另一种方案
            assigned[book]=false;
        }
    }
}

int main()
{
  Num=0;  //分书方案数初始值
  int book;
  for(book=0;book<5;book++)
    assigned[book]=false;
  //从第0个人(A)开始分书
  Try(0);
  return 0;
}

运行结果:


2.八皇后问题:

#include<iostream>
#include<iomanip>
using namespace std;
const int Normalize=9;  //用来统一数组下标
int Num;  //方案数
int q[9];  //8个皇后所占用的行号
bool S[9];  //S[1]~S[8],当前行是否安全
bool L[17];  //L[2]~L[16],(i-j)对角线是否安全
bool R[17];  //R[2]~R[16],(i+j)对角线是否安全

void Try(int col)
{
    //递归终止条件:所有列均已放上了皇后
    if(col==9)
    {
        Num++;
        //输出方案细节
        cout<<"方案"<<Num<<":";
        int i;
        for(i=1;i<=8;i++)
            cout<<q[i]<<" ";
        cout<<endl;
        return;
    }
    //依次尝试当前列的8行位置
    int row;
    for(row=1;row<=8;row++)
    {
        //判断拟放置皇后的位置是否安全
        if(S[row] && R[col+row] && L[col-row+Normalize])
        {
            //记录位置信息(行号)
            q[col]=row;
            //修改三个方向的安全性标记
            S[row]=false;
            L[col-row+Normalize]=false;
            R[col+row]=false;
            //尝试放下一列
            Try(col+1);
            //回溯:回复三个方向原有安全性
            S[row]=true;
            L[col-row+Normalize]=true;
            R[col+row]=true;
        }
    }
}

int main()
{
  //初始化
  Num=0;
  int i;
  for(i=0;i<9;i++)
    S[i]=true;  //各行都安全
  for(i=0;i<17;i++)
  {
      L[i]=true;  //个对角线都安全
      R[i]=true;
  }
  Try(1);  //从第一列开始放皇后
  return 0;
}

执行结果:



来自清华大学MOOC课件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值