机试指南第九章 搜索

P145 习题9.1

http://t.cn/Ai0lUhJj
在这里插入图片描述

#include <iostream>
#include <queue>
#include <vector>
#include <string>
#include <map>

using namespace std;

bool strhas2012(string str){//判断是否含有2012
    if (str.find("2012") == string::npos){return false;}
    return true;
}

bool strused(string str,vector <string> used){//字符串在之前已经出现过
    for (int i=0;i<used.size();i++){
        if (str == used[i]){return true;}
    }
    return false;
}

int BFS(string str){//宽度优先搜索
    queue <string> que;
    vector <string> used;
    map <string,int> m;//交换次数
    m.clear();
    m[str] = 0;
    que.push(str);//宽度搜索队列
    used.push_back(str);//字符串已经用过
    int answer = 0;
    bool yesflag = false;
    if (strhas2012(str)){return 0;}//本身就含有2012
    while (!que.empty()){
        string temp;
        temp = que.front();//取队头元素
        que.pop();
        for (int i=0;i<temp.size()-1;i++){
            string newstr = temp;
            char x;//字符串换位
            x = newstr[i];
            newstr[i] = newstr[i+1];
            newstr[i+1] = x;
            if (strused(newstr,used)){//(M.find(newStr)==M.end()
                continue;//字符串在之前已经判断过
            }
            m[newstr] = m[temp] + 1;//比上一次多一次交换
            used.push_back(newstr);
            if (strhas2012(newstr)){return m[newstr];}//第一次出现2012
            que.push(newstr);
        }
    }
    return -1;
}

int main(){
    //freopen("D://case.txt","r",stdin);
    string casestring;
    int b;
    cin>>b;
    cin>>casestring;
    cout<<BFS(casestring);
}

P152 习题9.2

http://t.cn/Ai0u0GUz

在这里插入图片描述
链接:https://www.nowcoder.com/questionTerminal/9aaea0b82623466a8b29a9f1a00b5d35
来源:牛客网

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 25;
const int total = 40; // 总重量
bool visit[MAXN]; // 标记数组
int matter[MAXN]; // 存放物品
int kind = 0; // 记录一共有多少种
int n; // 物品的数量

void DFS(int sum,int position) { // sum为当前已经凑的质量
    cout<<position<<endl;
    if(sum==total) {
        kind++; // 种数增加
        return;
    }
    // 从第一件开始凑数
    for(int i=position; i<n; i++) {
        if(visit[i] || sum+matter[i]>total) {
            continue;
        }
        visit[i] = true;
        DFS(sum+matter[i],i);
        visit[i] = false; // 回溯
    }
}

int main() {
    freopen("D://case.txt","r",stdin);
    cin>>n;
    int sum = 0; // 记录所有物品的质量总和
    for(int i=0; i<n; i++) {
        cin>>matter[i];
        sum+=matter[i];
    }
    sort(matter,matter+n);
    // 总和小于40或者最大的已经大于40了
    if(sum<40 || matter[0]>40) {
        cout<<kind<<endl;
        return 0;
    } else {
        memset(visit,false,sizeof(visit));
        DFS(0,0);
        cout<<kind<<endl;
    }
    return 0;
}

P152 习题9.3

http://t.cn/Ai0uOazs
在这里插入图片描述
牛客网莫名其妙
在这里插入图片描述

#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
#include <math.h>

using namespace std;

const int MAXN = 92+10;

vector <string> result;//结果序列
int matrix[8][8];

bool comp(string a,string b){
    return a<b;
}

bool judge(int x,int y){
    for(int i=1;i<=8;i++)if(matrix[i][y]==1)return 0;
    for(int i=1;i<=8;i++)if(matrix[x][i]==1)return 0;
    for(int i=1;i<min(x,y);i++)if(matrix[x-i][y-i]==1)return 0;
    for(int i=1;i<x&&y+i<9;i++)if(matrix[x-i][y+i]==1)return 0;
    return 1;
}

//状态row行号,num已放置的皇后数,结果字符串
//一行一行放
void DFS(int row,int num,string ender){
    if (row == 9){result.push_back(ender);}//八皇后已放置
    else {
        for (int i=1;i<9;i++){
            if (judge(row,i)){//如果可以放置
                matrix[row][i] = 1;//在row,i放置
                char x = i+'0';
                DFS(row+1,num+1,ender+x);//下一层DFS
                matrix[row][i] = 0;//回调
            }
        }
    }
}

int main(){
    //freopen("D://case.txt","r",stdin);
    int n;
    cin>>n;
    memset(matrix,0,sizeof(matrix));
    string str="";
    DFS(1,0,str);
    sort(result.begin(),result.end(),comp);
    while(n--){
        int x;
        cin>>x;
        cout<<result[x-1]<<endl;
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值