年功序列c++游戏
题目描述
在虚拟国度里多了很多 Virtual oier,为了树立对后辈的威信,从第 11 个 Virtual oier 开始的 oier 们搞起了年功序列的制度。
虚拟国度的创始人 oier Chtholly 感觉非常有趣,于是他决定观测 11 到 nn 这些人,他观测到了一些有趣的现象:虚拟国度里有一些凳子,如果 aa 是 的先辈则 能在 前面得到凳子
Chtholly的观测可以构成 mm 个序列,每个序列有 kk 个元素 a1,a2,a3,⋅⋅⋅⋅⋅⋅,aka1a 2a3,⋅⋅⋅⋅⋅⋅,a k。表示在 aia 有凳子前 a1,a2,a3,⋅⋅⋅⋅⋅⋅,ai−1a 1a2 ,a 3⋅⋅⋅⋅⋅⋅,a i−1必须有凳子。(ai−1a i−1是 aia的前辈)
例如 k = 3 时:a=1,2,3a=1,2,3,表示 33 有凳子前 1,21,2必须都有凳子,22 有凳子前 11 必须有凳子。
但 Chtholly 年纪大了记忆力未必好,如果第 ii 个序列与前 i−1i−1 个序列冲突的话那么就只需要考虑前 i−1i−1 个序列就好了。(忽略第 ii 个序列)
Chtholly 希望知道 11 到 nn 个人的年功序列的最小字典序。
输入格式
第一行两个数 n,mn,m
接下来 m 行每行第一个数为 kk,接下来 kk 个数为这次观测构成的序列
输出格式
输出 nn 个数构成的最小字典序。
样例
样例输入
4 3
3 1 2 3
2 4 2
3 3 4 1
样例输出
1 4 2 3
样例解释
第三个观测序列与前两个观测序列冲突不考虑,前两个观测序列可以构成 11 44 22 33 或者 44 11 22 33 这两个序列,字典序小的为 11 44 22 33。
数据范围与提示
3030%的数据,n≤10,m≤4n≤10,m≤4
5050%的数据,n≤10000,m≤5000n≤10000,m≤5000
100100%的数据,n≤100000,m≤50000,k≤nn≤100000,m≤50000,k≤n
题目分析
首先,如果不考虑有冲突的情况下,那这就是一道模板题了,也就是用优先队列的拓扑排序,于是,问题便变成如何处理冲突
首先有一个思路,就是用dfs,一个一个地添加序列,如果,拓扑排序满足的话,就可以直接输出了,但是,这个思路首先肯定会T,其次,可能不会满足字典序最小,于是,就又要想其他思路了
好好读题,会发现
如果第 i个序列与前 i+1个序列冲突的话那么就只需要考虑前 i个序列就好了。
思考一下,会发现,每一个序列满足必须是前一个序列满足,所以,如果有一个序列不满足,剩余的就不用输入了下一个问题,便成了如何判断可行
这时,回归拓扑排序的定义, 无环 ,也就是判断是否有环
for (int i = 0; i < g[x].size(); i++) //邻接表
{
if (vis[g[x][i]]) //已经走过
{
return 0;
}
vis[g[x][i]] = 1; //标记
if (!check(g[x][i])) //如果下一个顶点有环,说明,这张图都有环
{
return 0;
}
vis[g[x][i]] = 0;//回溯
}
return 1;
}
因为判断要用邻接表,所以,如果判断有环,我们要删去邻接表,顺便,就删去
入度的tot
for(int j=1;j<k;j++)
{
g[a[j]].pop_back();
tot[a[j+1]]--;
}
代码
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
int x, y;
int m;
int n;
int tot[100005];
vector<int> g[100005];
vector<int> ans;
int vis[100005];
int k;
int cnt = 0;
int a[100005];
priority_queue<int, vector<int>, greater<int> > q;
bool check(int x) {
for (int i = 0; i < g[x].size(); i++) //邻接表
{
if (vis[g[x][i]]) //已经走过
{
return 0;
}
vis[g[x][i]] = 1; //标记
if (!check(g[x][i])) //如果下一个顶点有环,说明,这张图都有环
{
return 0;
}
vis[g[x][i]] = 0;//回溯
}
return 1;
}
int main() {
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; i++) {
scanf("%d", &k);
for (int j = 1; j <= k; j++) {
scanf("%d", &a[j]);
if (j == 1) {
continue;
} // 1没有入度
g[a[j - 1]].push_back(a[j]);
tot[a[j]]++;
}
memset(vis, 0, sizeof(vis));
if (!check(a[1])) {
for (int j = 1; j < k; j++) {
g[a[j]].pop_back();
tot[a[j + 1]]--;
}
break;
}
}
for (int i = 1; i <= n; i++) {
if (!tot[i]) {
q.push(i);
}
}
while (!q.empty()) {
int k = q.top();
q.pop();
ans.push_back(k);
for (int i = 0; i < g[k].size(); i++) {
tot[g[k][i]]--;
if (!tot[g[k][i]]) {
q.push(g[k][i]);
}
}
}
for (int i = 0; i < ans.size(); i++) {
printf("%d ", ans[i]);
}
}
年功序列c++游戏的更多相关文章
- bzoj3255 一个关于序列的游戏
题意是啥 给你一个数列,可以任意删去一段,记其长度为$s$,得到$val_s$的价值,问你最大价值和为多少.. 其中这一段数要满足成一个上凸且相邻数差为$1$ 显然,删掉一段数后剩下的左右会相邻.. ...
- 【BZOJ-3675】序列分割 DP + 斜率优化
3675: [Apio2014]序列分割 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 1420 Solved: 583[Submit][Statu ...
- 第1部分: 游戏引擎介绍, 渲染和构造3D世界
原文作者:Jake Simpson译者: 向海Email:GameWorldChina@myway.com ---------------------------------------------- ...
- 【斜率DP】BZOJ 3675:[Apio2014]序列分割
3675: [Apio2014]序列分割 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 1066 Solved: 427[Submit][Statu ...
- 动态规划(斜率优化):BZOJ 3675 [Apio2014]序列分割
Description 小H最近迷上了一个分割序列的游戏.在这个游戏里,小H需要将一个长度为N的非负整数序列分割成k+l个非空的子序列.为了得到k+l个子序列, 小H将重复进行七次以下的步骤: 1.小 ...
- BZOJ 3675: [Apio2014]序列分割( dp + 斜率优化 )
WA了一版... 切点确定的话, 顺序是不会影响结果的..所以可以dp dp(i, k) = max(dp(j, k-1) + (sumn - sumi) * (sumi - sumj)) 然后斜率优 ...
- [BZOJ3675]序列分割
3675: [Apio2014]序列分割 Time Limit: 40 Sec Memory Limit: 128 MB Description 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H ...
- bzoj 3675: [Apio2014]序列分割
Description 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列分割成k+1个非空的子序列.为了得到k+1个子序列,小H需要重复k次以下的步骤: 1.小H首 ...
- 【BZOJ3675】序列分割(斜率优化,动态规划)
[BZOJ3675]序列分割(斜率优化,动态规划) 题面 Description 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列分割成k+1个非空的子序列.为了得 ...
随机推荐
- java通过JDBC访问数据库(最基本的查询)
一.步骤介绍 1.通过Class.forName()加载驱动: 2.通过DriverManager.getConnection()获取Conncetion连接对象: 3.创建Statement对象传递 ...
- Python enumerate():使用计数器简化循环
摘要:当您需要计数和迭代中的值时,Pythonenumerate()允许您编写 Pythonicfor循环.最大的优点enumerate()是它返回一个带有计数器和值的元组,因此您不必自己增加计数器. ...
- Windows FILETIME 与UNIX时间的转换
windows FILETIME时间从1601/01/01 零时零分零秒开始计时,windows每个时钟滴答将计数加一,每个时钟滴答的间隔是100 nanoseconds(纳秒,1秒=10的九次方纳秒 ...
- 转:android相对布局
android相对布局 Activity布局初步 - 相对布局 1. 相对布局的基本概念 一个控件的位置它决定于它和其他控件的关系,好处:比较灵活:缺点:掌握比较复杂. 2. 相对布局常用属性介绍 这 ...
- 转换…Transform…(Power Query 之 M 语言)
转换列: = Table.TransformColumns( 表, {{"列名1", 转换函数1, 数据类型1},-,{"列名n", 转换函数n, 数据类型n} ...
- CF1481B New Colony 题解
Content \(n\) 座山排成一行,其中第 \(i\) 座山的高度为 \(h_i\). 有 \(k\) 个巨石依次从第一座山开始滚落.当某个巨石在第 \(i\) 座山时: 如果 \(i=n\), ...
- CF1130A Be Positive 题解
Content 有一个长度为 \(n\) 的数组 \(a_1,a_2,a_3,...,a_n\),试找出一个数 \(d\),使得数组中的每个数除以 \(d\) 得到的 \(n\) 个结果中至少有 \( ...
- Docker从入门到精通(八)——Docker Compose
恭喜大家,学到这里,对于 docker 的基础玩法大家应该都会了,下面会介绍 docker的一些编排工具. 1.为什么需要 Docker Compose? 官网镇楼:https://www.runoo ...
- Visual Studio 2022有趣又强大的智能辅助编码
工欲善其事,必先利其器 作为一名.Net开发人员,开发利器当然是首选微软自家的:宇宙第一IDE - Visual Studio了. 这不 VS 2022 正式版已经发布近两个月了,我也体验了近两个月, ...
- Oracle使用数据泵导入/导出数据(expdp/impdp)
Oracle使用数据泵导入/导出数据(expdp/impdp) A电脑上的操作(expdp数据导出) 运行cmd: 登录数据库,输入命令:sqlplus 使用管理员角色登录需要在用户名后加" ...