ZZUOJ 1199: 大小关系

4 篇文章 0 订阅

题目描述

当我们知道一组大小关系之后,可判断所有关系是否都能成立,即关系间没有矛盾。

例如:A<B, A<C, B<C 通过这组关系我们可以得到A<B<C ,所有关系都成立,没有矛盾。

若 A<B, B<C, C<A 通过前两个关系我们得到 A<B<C ,这个关系与C<A矛盾,所有关系不能同时成立。

现在我们知道m个关系,请判断这m个关系是否能成立,成立输出“YES”,否则输出“NO”。

输入
多组数据,每组数据如下:

第一行有一个数字m。 m代表m组关系(1<=m<=400),接下来m行每行有一个关系,用两个不同的字母和一个符号表示。(输入保证字母在‘A’-‘Z’之间,关系符号只有 > , <)

输出
对于每组数据输出“YES”或“NO”.

样例输入
3
A<B
A<C
B<C

3
A<B
B<C
C<A
样例输出
YES

NOZZUOJ 1199题链接


这道题比赛的时候开始就有了思路,不过整整做了一个半小时才做完, 中间各种出错吧,一直在调试,这道题的思路是用一个邻接表和深搜解决!

具体怎么做代码中会有注释  光说太罗嗦

#include<stdio.h>
#include<stdlib.h>

struct temp{
	char k;
	struct temp *next;
};//这是邻接表的存储结构,邻接表后面只存正确且比自己大的字母 
struct cmp{
	struct temp *s;
}b[100];//这是邻接表的头 ,在这有一个技巧就是A~Z的ascii值是从65~90的这样b[65]~b[90]直接代表了
//b[A]~b[Z] 
struct temp * f()//这个函数是申请空间 
{
	struct temp *p;
	return p = (struct temp *)malloc(sizeof(struct temp));
}
int DFS(struct temp *w, char z)//这个是深搜函数,深搜的思路是把传入的两个字母较大的那个字母开始搜索
//如果在深搜过程中找到了较小的值 则返回值为零  找不到返回一 
{

	while(w != NULL)
	{
	    if( w -> k == z )
		return 0;	
		else if(DFS(b[w -> k].s, z) == 0)
		return 0;
		w = w -> next;	
	}	
	return 1;
}
int main()
{
	int n, i, k, ok;
	struct temp *p, *q;
	char x, y, ch, a[5];
	while(scanf("%d", &n) != EOF)
	{
		for(i = 60; i < 100; i++)
			b[i].s = NULL;
			ok = 1;
		for(i = 0; i < n; i++)
		{
			scanf("%s", a);
			if(0 == ok)//如果中间出现错误下面就不用判断了直接停止就可以了 
				continue;//我得思路这一句一定得加,否则提交会超时,比赛时加了这句直接过了 
				//不过刚刚提交时少了这句超时,因为是递归  已经错了 还继续往下的话会把时间延长很多 
			x = a[0];  y = a[2]; ch = a[1];
			if(ch == '<')
			{
				if(DFS(b[y].s, x))
				{
					p = f();
					p -> k = y;
					q = b[x].s;
					b[x].s = p;
					p -> next = q;
				}
				else
				{
					ok = 0;
				}
			}	
			else if( ch == '>' )
			{
				if( DFS(b[x].s, y) )
				{
					p = f();
					p -> k = x;
					q = b[y].s;
					b[y].s = p;
					p -> next = q;	
				}
				else 
				{
					ok = 0;
				}
			}		
		}
		if(1 == ok)
			printf("YES\n");
		else if(0 == ok)
			printf("NO\n");	
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值