0
点赞
收藏
分享

微信扫一扫

蓝桥杯 - 3000米排名预测


题目链接:​​点击打开链接​​

题目大意:略。

解题思路:全排列 + 限制条件(judge()函数注释)。

AC 代码

#include<bits/stdc++.h>

#define mem(a,b) memset(a,b,sizeof a);

using namespace std;

typedef long long ll;

/*
len:记录有多少排名的可能个数
vis:是否使用过该点
num:存储预备的数据
rcd:记录符合题意的数据(从num[]获取)
rs:记录最终符合题意的所有数据(从rcd[]获取)
mk:记录预判信息
*/
int n,m,len,vis[20],mk[20][20],num[20],rcd[20],rs[1000000][20];

// 初始化
void init()
{
len=0;
mem(mk,0);
for(int i=0;i<20;i++) // 预备存储数据,取决于题目是需要存储什么类型的数据
num[i]=i;
mem(vis,0);
mem(rcd,0);
mem(rs,0);
}

// 判断是否符合正确的预判
int judge()
{
// f1:标记预判为1的结果; f2:标记预判为0的结果
int f1=1,f2=1;
for(int i=0;i<m;i++) // 通过记录个数判断是否符合预判为1的限定
{
if(mk[i][mk[i][0]+1]==1&&f1)
{
int j=1;
for(int x=0; j<=mk[i][0]&&x<n; x++)
{
if(mk[i][j]==rcd[x])
j++;
}

if(j<mk[i][0]+1) // +1 因为上面 j 先 ++,再判断
f1=0;
}
else // 通过记录个数判断是否符合预判为0的限定
{
int j=1;
for(int x=0; j<=mk[i][0]&&x<n; x++)
{
if(mk[i][j]==rcd[x])
j++;
}
if(j==mk[i][0]+1) // 同上
f2=0;
}

if(!f1 || !f2)
{
break;
}
}

if(f1&&f2)
return 1;
else
return 0;
}

void dfs(int l)
{
if(l==n&&judge())
{
for(int i=0;i<n;i++) // 记录每一组符合题意的数据
{
rs[len][i]=rcd[i];
}
len++;
return;
}

for(int i=0;i<n;i++)
{
if(!vis[i])
{
vis[i]=1;
rcd[l]=num[i];
dfs(l+1);
vis[i]=0;
}
}
}

int main()
{
while(~scanf("%d%d",&n,&m))
{
init();
for(int k=0;k<m;k++)
{
int c; scanf("%d",&c);
mk[k][0]=c; // 记录长度
for(int i=1;i<=c+1;i++) // +1 记录后面预判(1、0)
scanf("%d",&mk[k][i]);
}

dfs(0); // 从第0号球员开始搜

printf("%d\n",len);
for(int i=0;i<len;i++)
{
for(int j=0;j<n;j++)
printf("%d ",rs[i][j]);
puts("");
}
}

return 0;
}


举报

相关推荐

【蓝桥杯】

蓝桥杯,,,,,,

蓝桥杯自用

【蓝桥杯】旋转

蓝桥杯模板

蓝桥杯——礼物

蓝桥杯01

直线(蓝桥杯)

蓝桥杯练习

0 条评论