2012百度之星初赛——A题

A:度度熊就是要第一个出场
时间限制:
1000ms
内存限制:
65536kB
描述
Baidu年会安排了一场时装秀节目。N名员工将依次身穿盛装上台表演。表演的顺序是通过一种“画线”抽签的方式决定的。
首先,员工们在一张白纸上画下N条平行的竖线。在竖线的上方从左到右依次写下1至N代表员工的编号;在竖线的下方也从左到右依次写下1至N代表出场表演的次序。

接着,员工们随意在两条相邻的竖线间添加垂直于竖线的横线段。

最后,每位员工的出场顺序是按如下规则决定的:每位员工从自己的编号开始用手指沿竖线向下划,每当遇到横线就沿横线移动到相邻的竖线上去,直到手指到达竖线下方的出场次序编号。这时手指指向的编号就是该员工的出场次序。例如在下图的例子中,度度熊将第二名出场,第一名出场的是员工4。

员工在画横线时,会避免在同一位置重复画线,并且避免两条相邻的横线连在一起。即下图所示的情况是不会出现的:

给定一种画线的方案,员工编号为K的度度熊想知道自己是不是第一位出场表演的。如果不是,度度熊想知道自己能不能通过增加一条横线段来使得自己变成第一位出场表演。
输入
为了描述方便,我们规定写有员工编号的方向是y轴正方向(即上文中的竖线上方),写有出场次序的方向是y轴负方向(即上文中的竖线下方)。竖线沿x轴方向(即上文中从左到右)依次编号1至N。于是,每条横线的位置都可以由一个三元组确定,其中xl, xr是横线左右两个端点所在竖线的编号,y是横线的高度。


输入第一行是一个整数T(T <= 50),代表测试数据的组数。
每组数据的第一行包含三个整数N, M, K( 1<=N<=100, 0<=M<=1000, 1<=K<=N),分别代表参与表演的员工人数、画下的横线数目以及度度熊的员工编号。
每组数据的第2-M+1行每行包含3个整数, xl, xr, y, (1 <= xl < N, xr = xl + 1, 0 <= y <= 1,000,000),描述了一条横线的位置。
输出
对于每组数据输出一行Yes或者No,表示度度熊能否通过增加一条横线段来使得自己变成第一位出场表演。如果度度熊已经是第一位出场表演,也输出Yes。注意,尽管输入数据中员工画的横线高度都是整数,但是度度熊可以在任意实数高度画横线。此外,度度熊和员工一样,在画横线时需要避免在同一位置重复画线,也要避免两条相邻的横线连在一起。
样例输入
2
4 6 3
1 2 1
1 2 4
1 2 6
2 3 2
2 3 5
3 4 4
4 0 3
样例输出
Yes
No









===============================================================================================================================

2个小时,没做出来,后来做了,不知道能不能AC:

#include<stdio.h>

int min(int a[],int b[],int c[],int n,int k,int mark[],int* x)
{
	int i,markres=1;
	int min=10000,minindex;
	for(i=0;i<n;i++)
	{
		markres&=mark[i];
	}
	if(markres)
		return -1;
	else
	{
		for(i=0;i<n;i++)
		{
			if(!mark[i]&&c[i]<min&&(a[i]==k||b[i]==k))
			{
				minindex=i;
				min=c[i];
				mark[i]=1;
				if(a[i]==k)
					*x=1;
				if(b[i]==k)
					*x=2;
			}
		}
		for(i=0;i<n;i++)
		{
			if(c[i]<=min&&a[i]!=k&&b[i]!=k)
				mark[i]=1;
		}
		return minindex;
	}
}

int getny(int mark[],int n)
{
	int i,res=0;
	for(i=0;i<n;i++)
	{
		if(mark[i]==0)
			res++;
	}
	return res;
}

void judge(int xl[],int xr[],int y[],int mark[],int n,int N,int M,int K,int firstK)
{
	int x;
	int ny=M;
/*
	if(ny==1&&(K==firstK-1||K==firstK+1))
	{
		printf("Yes\n");
		return;
	}
	if(ny==1&&K!=firstK-1&&K!=firstK+1)
	{
		printf("No\n");
		return;
	}
*/
	int minres=min(xl,xr,y,n,K,mark,&x);
	if(minres>=0)
	{
		mark[minres]=1;
		if(x==1)	K+=1;
		if(x==2)	K-=1;
		ny=getny(mark,n);
		judge(xl,xr,y,mark,n,N,ny,K,firstK);
	}
	else
	{
		if(K==firstK-1||K==firstK+1)
		{
			printf("Yes\n");
		}
		else
			printf("No\n");
		return;
	}
}


int main()
{
	int T,N,M,K,tempM;
	int xl[10000],xr[10000],y[10000],i=0,mark[10000]={0};
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d%d",&N,&M,&K);
		tempM=M;
		if(tempM==0)
		{	
			printf("No\n");
		}
		else
		{
			while(M--)
			{
				scanf("%d%d%d",&xl[i],&xr[i],&y[i]);
				i++;
			}

			judge(xl,xr,y,mark,i,N,tempM,K,K);		
		}
		i=0;

	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值