#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
using namespace std; const int maxn = + ;
const int maxP = + ;
struct Predict {
int nPre; //n个预测
int rSort[maxn]; //n个人编号相对排序
int isOk; //正确否
} pre[maxn]; //围观人的预测 int n, m; //运动员n,围观人m
int ans; //预测的可能数
int predict[maxP][maxn];//正确的排名
int pre_o[maxn]; //一次正确的排名
bool used[maxn]; //标志数组
void input(); //输入
bool check();
void DFS(int n);
void solve(); //输入
void input()
{
memset(used, , sizeof(used));
scanf("%d%d", &n, &m);
for (int i = ; i < m; i++) {
scanf("%d", &pre[i].nPre);
for (int j = ; j < pre[i].nPre; j++) {
scanf("%d", &pre[i].rSort[j]);
}
scanf("%d", &pre[i].isOk);
}
} bool check()
{
bool flag_1 = true,
flag_2 = true;
for (int i = ; i < m; i++)
{
//预测正确 且 标志是正确标志
if (pre[i].isOk && flag_1)
{
int j = ; //代表预测数的索引
//k--运动员总数
for (int k = ; j < pre[i].nPre && k < n; k++) //k代表第几个选手
{
//预测位置 == 运动员正确位置
if (pre[i].rSort[j] == pre_o[k]) {
j++;
}
}
if (j < pre[i].nPre) { //有位置不等于正确排序 (pre_o和正确的预测不一致,则false)
flag_1 = false;
}
}
else
{
int j = ;
for (int k = ; j < pre[i].nPre && k < n; k++)
{
if (pre[i].rSort[j] == pre_o[k]) {
j++;
}
}
if (j == pre[i].nPre) { //pre_o和不正确的预测一致,所以也应该是false
flag_2 = false;
}
}
if (!flag_1 || !flag_2) break; //有一个错误即错误
}
if (flag_1 && flag_2) return true;
else return false;
} //超时???
void DFS(int cur)
{
if (cur == n && check()) //结束条件
{
for (int i = ; i < n; i++) { //用dfs,亦是 所有排名按字典序依次输出。
predict[ans][i] = pre_o[i]; //每种可能下的,排名
}
ans++; //方案数++
}
//当前人小于参赛总数
if (cur < n)
{
for (int i = ; i < n; i++)
{
if (!used[i]) //判断当前人是否排序过
{
pre_o[cur] = i; //设置当前预测
used[i] = true; //当前人标志为访问过
DFS(cur + ); //下一个人
used[i] = false; //重新标志为false
}
}
}
} void DFS_2(int n) //用STL的话,全排列这段代码就够了
{
for (int i = 0; i < n; i++) pre_o[i] = i;
do {
if (check()) {
for (int i = 0; i < n; i++) {
predict[ans][i] = pre_o[i];
}
ans++;
}
} while (next_permutation(pre_o, pre_o + n));
} //处理函数
void solve()
{
input();
// DFS(0);
DFS_2(n);
printf("%d\n", ans);
for (int i = ; i < ans; i++)
{
printf("%d", predict[i][]);
for (int j = ; j < n; j++) { //n个运动员的排名
printf(" %d", predict[i][j]);
}
printf("\n");
}
} int main()
{
solve();
return ;
}

//一开始使用了自己写的全排列,然后对排列进行check判断,超时了.....

//然后使用了 STL里的 next_permutation(a, a + n) 然后才过

套路总结:

1. 第一步还是先写下面模板

const int maxn =  + ;
const int maxP = + ;
struct Predict {
int nPre; //n个预测
int rSort[maxn]; //n个人编号相对排序
int isOk; //正确否
} pre[maxn]; //围观人的预测 int n, m; //运动员n,围观人m
int ans; //预测的可能数
int predict[maxP][maxn];//正确的排名
int pre_o[maxn]; //一次正确的排名
bool used[maxn]; //标志数组
void input(); //输入
bool check(); //发现check()是DFS水题里面最重要的一步了!!几乎这个能想出来,整个题目就差不多了
void DFS(int n); //自己写的全排列....超时了......
void DFS_2(int n); //next_permutation()
void solve();

//下对check进行分析

//主要就是全排列0~n-1的可能,然后用预测的结果与其比较

//预测正确, 则看是否全排列等于该预测结果,不 一致,则该排列不正确, return false

//预测错误, 则看是否全排列等于该预测结果, 一致,   则该排列不正确, return false

//check()返回true, 则应该将预测结果添加到总的predict[ans][i]中, (结果数)ans++;

bool check()
{
bool flag_1 = true,
flag_2 = true;
for (int i = ; i < m; i++)
{
//预测正确 且 标志是正确标志
if (pre[i].isOk && flag_1)
{
int j = ; //代表预测数的索引
//k--运动员总数
for (int k = ; j < pre[i].nPre && k < n; k++) //k代表第几个选手
{
//预测位置 == 运动员正确位置
if (pre[i].rSort[j] == pre_o[k]) {
j++;
}
}
if (j < pre[i].nPre) { //有位置不等于正确排序 (pre_o和正确的预测不一致,则false)
flag_1 = false;
}
}
else
{
int j = ;
for (int k = ; j < pre[i].nPre && k < n; k++)
{
if (pre[i].rSort[j] == pre_o[k]) {
j++;
}
}
if (j == pre[i].nPre) { //pre_o和不正确的预测一致,所以也应该是false
flag_2 = false;
}
}
if (!flag_1 || !flag_2) break; //有一个错误即错误
}
if (flag_1 && flag_2) return true;
else return false;
}

蓝桥杯 算法提高 3000米排名预测 DFS 递归搜索 next_permutation()使用的更多相关文章

  1. Java实现 蓝桥杯VIP 算法提高 3000米排名预测

    算法提高 3000米排名预测 时间限制:1.0s 内存限制:256.0MB 问题描述 3000米长跑时,围观党们兴高采烈地预测着最后的排名.因为他们来自不同的班,对所有运动员不一定都了解,于是他们分别 ...

  2. 蓝桥杯--算法提高 排列数 (简单dfs)

    算法提高 排列数   时间限制:1.0s   内存限制:256.0MB      问题描述 0.1.2三个数字的全排列有六种,按照字母序排列如下: 012.021.102.120.201.210 输入 ...

  3. C语言 · 3000米排名预测

    算法提高 3000米排名预测   时间限制:1.0s   内存限制:256.0MB      问题描述 3000米长跑时,围观党们兴高采烈地预测着最后的排名.因为他们来自不同的班,对所有运动员不一定都 ...

  4. 问题 1936: [蓝桥杯][算法提高VIP]最大乘积

    问题 1936: [蓝桥杯][算法提高VIP]最大乘积 时间限制: 1Sec 内存限制: 128MB 提交: 77 解决: 16 题目描述 对于n个数,从中取出m个数,如何取使得这m个数的乘积最大呢? ...

  5. 蓝桥杯 算法提高 11-1实现strcmp函数 (JAVA方法)

    蓝桥杯 算法提高 11-1实现strcmp函数 (JAVA方法) 首先这不是一个多难的题,但是网上的我没怎么找到有Java的代码,基本全都是c语言的,小编是个小白,如果有不对的地方请联系小编 问题描述 ...

  6. Java实现 蓝桥杯 算法提高 成绩排名

    试题 算法提高 成绩排名 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 小明刚经过了一次数学考试,老师由于忙碌忘记排名了,于是老师把这个光荣的任务交给了小明,小明则找到了聪明的你, ...

  7. Java实现 蓝桥杯 算法提高 进攻策略加强(暴力)

    试题 算法提高 进攻策略加强 问题描述 植物大战僵尸这款游戏中,还有一个特别的玩儿法:玩家操纵僵尸进攻植物. 首先,僵尸有m种(每种僵尸都是无限多的),玩家可以选择合适的僵尸来进攻.使用第i种僵尸需要 ...

  8. Java实现 蓝桥杯 算法提高 小X的购物计划

    试题 算法提高 小X的购物计划 问题描述 小X打算去超市shopping.小X没什么钱,只有N元.超市里有M种物品,每种物品都需要money,在小X心中有一个重要度.有的物品有无限件,有的物品只有几件 ...

  9. 蓝桥杯算法提高 P1001(大数乘法)

      算法提高 P1001   时间限制:1.0s   内存限制:256.0MB   当两个比较大的整数相乘时,可能会出现数据溢出的情形.为避免溢出,可以采用字符串的方法来实现两个大数之间的乘法. 具体 ...

随机推荐

  1. The user survey(用户调查)

    在周末,我们找了一些人来进行了一个调查,鉴于选择困难,我们只找到了几个真正的小学生,没有找到家长,其余那些都是找大学生来做调查的,我们和他们说,让他们把自己的立场看成是小学生或家长.下面是我们整理出来 ...

  2. 个人作业2——APP案例分析

    产品:网易LOFTER(乐乎)   网易LOFTER是网易旗下图片社交APP,产品覆盖web及移动各端. 网易LOFTER社区内汇聚了多领域的品质生活家与生活达人,包含女神.明星.穿搭.文具.旅行.美 ...

  3. Hadoop到底能做什么?怎么用hadoop?

    hadoop是什么?(1)Hadoop是一个开源的框架,可编写和运行分布式应用处理大规模数据,是专为离线和大规模数据分析而设计的,并不适合那种对几个记录随机读写的在线事务处理模式.Hadoop=HDF ...

  4. Delphi 判断TImage是否为空及注意事项

    Delphi 判断TImage是否为空:1)非空 Image1.Picture.Graphic <> nil2)为空 Image1.Picture.Graphic = nil注意不能用Im ...

  5. 隐藏基于Dialog的MFC的主窗体

    最近需要做一个主窗体常态隐藏的程序,类似360卫士那样,只有托盘图标常显示.本以为隐藏主窗体很简单,但遇到了意想不到的情况. 无效的做法 最初的想法是设置主对话框资源的 Visiable 属性为 fa ...

  6. java中的==操作符和equals函数

    基本规则 “==”操作符的使用需要分成两种情况 判值类型相等 这一点很好理解,两个值类型代表的数值相等,则“==”表达式返回true “==”可以用与不同值类型的比较,语言会自动进行类型转换 判引用类 ...

  7. matlab dist函数

    dist——欧式距离加权函数(Euclidean distance weight function) 语法: Z = dist(W,P)    df = dist('deriv')    D = di ...

  8. Python教程:丛入门到实践

    一.特殊用法的函数 name = "python very good" print(name.title()) 方法是python可对数据执行的操作.每个方法后面都跟着一对括号. ...

  9. 【大数据】MapTask并行度和切片机制

    一. MapTask并行度决定机制 maptask的并行度决定map阶段的任务处理并发度,进而影响到整个job的处理速度 那么,mapTask并行实例是否越多越好呢?其并行度又是如何决定呢? 1.1 ...

  10. P3216 [HNOI2011]数学作业

    题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 N 和 M ,要求计算Concatenate (1 .. N) Mod M 的值,其中 Concatenat ...