当前位置: 首页 > news >正文

【递归完全搜索】USACO Bronze 2019 December - 奶牛排列Livestock Lineup

题目描述

每天,农夫约翰都会给他的 888 头奶牛挤奶,它们的名字分别是 BessieButtercupBelindaBeatriceBellaBlueBetsySue

不幸的是,这些奶牛非常挑剔,要求农夫约翰必须按照满足 N 条约束条件 的顺序来给它们挤奶(1≤N≤71 ≤ N ≤ 71N7)。

每条约束的格式为:“X 必须和 Y 相邻挤奶”,意思是奶牛 X 必须出现在挤奶顺序中 紧挨着奶牛 Y 的前面或后面

请帮助农夫约翰确定一个满足所有约束条件的奶牛排列顺序。保证至少存在一种满足条件的顺序。如果有多个顺序满足条件,请输出字典序最小的顺序。即:

  • 第一个位置应该选择所有可能的奶牛中名字字典序最小的;
  • 如果第一个位置固定后有多个顺序,第二个位置选择字典序最小的,以此类推。

输入格式

第一行是整数 NNN

接下来的 NNN 行中,每行都是一个约束,格式如下:X must be milked beside Y

其中 XXXYYY 是奶牛的名字(名字只会是上述 888 个中的一个)。

输出格式

输出满足所有约束条件的奶牛排列顺序,共 888 行,每行输出一头奶牛的名字。

样例输入

3
Buttercup must be milked beside Bella
Blue must be milked beside Bella
Sue must be milked beside Beatrice

样例输出

Beatrice
Sue
Belinda
Bessie
Betsy
Blue
Bella
Buttercup

提交链接

Livestock Lineup

思路分析

关键点

只有 888 头奶牛,所有排列数量是 :8!=40320,完全可以暴力枚举。

next_permutation 可以生成按字典序排列的全排列,第一个合法解就是字典序最小解。

解决步骤

  1. 读入 NNN 条约束,把每条约束中的两头奶牛记录下来。

  2. 888 头奶牛的名字按字典序排序。

  3. 枚举所有排列,每次检查所有约束是否满足。

  4. 找到第一个合法排列后输出并结束。

如何实现这些步骤?

  1. 读取输入

    使用 getline 读入整行约束,然后提取开头和结尾的奶牛名字。

  2. 存储约束

    把每条约束保存为 pair<string,string>,存入数组。

  3. 排列生成

    将所有奶牛名字放到 vector,排序后用 next_permutation 生成所有字典序排列。

  4. 合法性检查

    对每个排列,遍历所有约束,找出两头奶牛的位置索引,若不相邻则判为不合法。

  5. 输出结果

    第一次遇到合法排列后输出所有奶牛名字,每行一个,然后结束程序。

参考代码

#include <bits/stdc++.h>
using namespace std;int n;
pair<string, string> p[10];
string change(string art)
{string c;for (auto it : art){if (it == ' ')break;c += it;}return c;
}
int main()
{// freopen("lineup.in" , "r" , stdin);// freopen("lineup.out" , "w" , stdout);cin >> n; // n条限制条件getchar();for (int i = 0; i < n; i++){string art;getline(cin, art); // 限制条件// 得到2个奶牛的名字 c1  c2string c1, c2;c1 = change(art);reverse(art.begin(), art.end());c2 = change(art);reverse(c2.begin(), c2.end());p[i] = {c1, c2};}vector<string> cow{"Bessie", "Buttercup", "Belinda", "Beatrice", "Bella", "Blue", "Betsy", "Sue"};sort(cow.begin(), cow.end());do{bool check = true;for (int i = 0; i < n; i++){int l = 0, r = 0;for (int j = 0; j < 8; j++){if (cow[j] == p[i].first)l = j;if (cow[j] == p[i].second)r = j;}if (abs(l - r) != 1)check = false;}if (check){for (auto it : cow)cout << it << endl;break;}} while (next_permutation(cow.begin(), cow.end()));return 0;
}

官方代码

#include <bits/stdc++.h>
using namespace std;int N;
int main() {freopen("lineup.in", "r", stdin);freopen("lineup.out", "w", stdout);cin >> N;vector<pair<string, string>> restrictions;for (int i = 0; i < N; i++) {string a, t, b;cin >> a;cin >> t >> t >> t >> t;cin >> b;restrictions.push_back({a, b});}vector<string> cows = {"Bessie", "Buttercup", "Belinda", "Beatrice","Bella",  "Blue",      "Betsy",   "Sue"};sort(cows.begin(), cows.end());int count = 0;while (next_permutation(cows.begin(), cows.end())) {bool passed = true;for (auto p : restrictions) {string cow1 = p.first;string cow2 = p.second;auto a = find(cows.begin(), cows.end(), cow1);auto b = find(cows.begin(), cows.end(), cow2);if (abs(a - b) != 1) { passed = false; }}if (passed) { break; }}for (auto cow : cows) { cout << cow << endl; }
}
http://www.dtcms.com/a/317307.html

相关文章:

  • 每日算法刷题Day57:8.6:leetcode 单调栈6道题,用时2h
  • 【前端开发】五. ES5和ES6对比
  • Android 之 Kotlin中的符号
  • OpenObserve非sql模式 query editor 中 xx like ‘|’报错如何处理
  • RNN梯度爆炸/消失的杀手锏——LSTM与GRU
  • Disruptor 的原理、应用场景
  • jspdf或react-to-pdf等pdf报错解决办法
  • iOS混淆工具有哪些?在集成第三方 SDK 时的混淆策略与工具建议
  • Java Socket -- UDP通信
  • CSS 回流(Reflow)和重绘(Repaint)
  • C语言基础_排序算法和二分法查找
  • TDengine IDMP 背后的技术三问:目录、标准与情景
  • 自学嵌入式 day43 中断系统
  • 1-知识图谱—知识图谱表示与建模:给知识 “搭框架”,让每句话都有条理
  • Java学习第一百一十一部分——Jenkins(二)
  • 开源流媒体服务器ZLMediaKit 的Java Api实现的Java版ZLMediaKit流媒体服务器-二开视频对话
  • 周鸿祎:AI 时代安全智能体,能否重塑数字安全格局?
  • 【数据库】Oracle学习笔记整理之一:ORACLE的核心组成部分
  • 亚矩阵云手机:解锁 Shopee/Lazada 东南亚电商运营“通关密码
  • Cortex-M MCU 默认的分散加载文件分析
  • CSS高频属性速查指南
  • SG105 Pro 网管交换机的3种VLAN配置
  • Uniapp生物识别(SOTER)
  • 什么是逻辑外键?我们要怎么实现逻辑外键?
  • 【C++详解】STL-set和map的介绍和使用样例、pair类型介绍、序列式容器和关联式容器
  • sqli-labs靶场less40-less45
  • uniapp 通用地磅称重系统手机端
  • 生成网站sitemap.xml地图教程
  • android 设置字体样式
  • QT----QAxObject在子线程中调用,发现excel指针为空