#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. 高可用集群(crmsh详解)http://www.it165.net/admin/html/201404/2869.html

    crmsh是pacemaker的命令行接口工具,执行help命令,可以查看shell接口所有的一级命令和二级命令,使用cd 可以切换到二级子命令的目录中去,可以执行二级子命令 在集群中的资源有四类:p ...

  2. 简单复利计算c语言实现

    #include<stdio.h>#include<math.h>float i; //利率 float p; //期初金额 float F; //未来值 int n; //期 ...

  3. git常用命令复习及其基本使用示例

    年后回来新上到项目,对于git的一些操作命令记得有点混乱了,所以特整理笔记如下: 一.git常用命令复习 查看当前分支:git branch (显示结果中带有*号的是当前分支)查看所有分支: git ...

  4. win7系统安装SQLServer2000的详细步骤(图文)

    首先,如果以前安装的话,要删除干净.我也找了半天的网络资料.1.把原来SQLServer的安装目录 C:\Program Files\Microsoft SQL Server  删除2.所有SQLSe ...

  5. lr常见问题汇总(持续更新版)

    在使用mms协议的时候,会碰到报错 Action.c(): 错误: C 解释器运行时错误: Action.c (): Error -- Unresolved symbol : mms_play. 解决 ...

  6. 使用robot封装一个模拟键盘复制粘贴并按下回车的方法

    /** * 复制数据到剪切板并粘贴出来并按下回车 * @param writeMe 需要粘贴的地址 * @throws java.awt.AWTException */ public void use ...

  7. java中为什么要进行对象序列化?

    序列化其实很好理解,假如你现在做一个项目,项目是分工合作的,并且你喝其他小组成员不在同一个城市,那么你要如何把你写的那些类给其他小组成员呢?这个时候就要用到序列化了,简单的说:序列化就是将内存中的类或 ...

  8. 第216天:Angular---自定义指令(二)

    自定义指令 1.第一个参数是指令的名字,第二个参数任然应该使用一个数组,数组的最后一个元素是一个函数.定义指令的名字,应该使用驼峰命名法 <!DOCTYPE html> <html ...

  9. PGM学习之三 朴素贝叶斯分类器(Naive Bayes Classifier)

    介绍朴素贝叶斯分类器的文章已经很多了.本文的目的是通过基本概念和微小实例的复述,巩固对于朴素贝叶斯分类器的理解. 一 朴素贝叶斯分类器基础回顾 朴素贝叶斯分类器基于贝叶斯定义,特别适用于输入数据维数较 ...

  10. MT【121】耐克数列的估计

    已知$\{a_n\}$满足$a_1=1,a_2=2,\dfrac{a_{n+2}}{a_n}=\dfrac{a_{n+1}^2+1}{a_n^2+1}$, 求$[a_{2017}]$_____ 解:容 ...