食物链 2001年NOI全国竞赛
动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形。A吃B,B吃C,C吃A。
现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种。
有人用两种说法对这N个动物所构成的食物链关系进行描述:
第一种说法是“1 X Y”,表示X和Y是同类。
第二种说法是“2 X Y”,表示X吃Y。
此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。
1) 当前的话与前面的某些真的话冲突,就是假话;
2) 当前的话中X或Y比N大,就是假话;
3) 当前的话表示X吃X,就是假话。
你的任务是根据给定的N(1<=N<=50,000)和K句话(0<=K<=100,000),输出假话的总数。
第一行是两个整数N和K,以一个空格分隔。
以下K行每行是三个正整数D,X,Y,两数之间用一个空格隔开,其中 D 表示说法的种类。
若D=1,则表示X和Y是同类。
若D=2,则表示X吃Y。
只有一个整数,表示假话的数目。
100 7
1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5
3
输入文件
对7句话的分析 100 7
1 101 1 假话
2 1 2 真话
2 2 3 真话
2 3 3 假话
1 1 3 假话
2 3 1 真话
1 5 5 真话
NOI 2001 食物链(eat)
这道题可以用加权并查集解决。
三个元素集,三个n个元素组成的数组(我放到一个数组里了)。
A---x||y,B---(x||y)+n,C---(x||y)+n*2,
如果x,y同类,则要使A-x<---A-y&&B-x<---B-y&&C-x<---C-y。
如果x吃y,则要使A-x<---B-y&&B-x<---C-y&&C-x<---A-y。
代码实现:
#include<cstdio>
int n,k,d,x,y,ans;
int v[];
int find(int x){if(v[x]!=x) v[x]=find(v[x]);return v[x];}
int main(){
scanf("%d%d",&n,&k);
for(int i=;i<=*n;i++) v[i]=i;
for(int i=;i<=k;i++){
scanf("%d%d%d",&d,&x,&y);
if(x>n||y>n||(d==&&x==y)){++ans;continue;}//x和y不能非法,自己不能吃自己。
if(d==){
if(find(x)==find(y+n)||find(x)==find(y+n*)) ++ans;//x和y不能互吃。
else{
v[find(y)]=find(x);
v[find(y+n)]=find(x+n);
v[find(y+n*)]=find(x+n*);
}
}
if(d==){
if(find(x)==find(y)||find(x)==find(y+n*)) ++ans;//x和y不是同类,y也不能吃x。
else{
v[find(y+n)]=find(x);
v[find(y+n*)]=find(x+n);
v[find(y)]=find(x+n*);
}
}
}
printf("%d\n",ans);
return ;
}
注意:有关判断的问题,因为高度有序,所以只需要判断一个条件即可确定某一情况是否存在。
读入输出等优化(codevs 54ms 洛谷62ms):
#include<cstdio>
#include<string>
using namespace std;
int n,k,d,x,y,ans,l,re;
int ax,bx,cx,ay,by,cy;
int v[];
char ch[];
inline int find(int x){if(v[x]!=x) v[x]=find(v[x]);return v[x];}
int read(){
l=re=;
while(ch[l]=getchar())
if(ch[l]>=''&&ch[l]<='') break;
l++;
while(ch[l]=getchar()){
if(ch[l]>=''&&ch[l]<='') l++;
else break;
}
for(int i=;i<l;i++) re=re*+ch[i]-'';
return re;
}
void write(int x){
l=;
while(x){ch[l++]=x%+'';x/=;}
for(int i=l-;i>=;i--) putchar(ch[i]);
putchar('\n');
}
int main(){
n=read();k=read();
for(int i=;i<=*n;i++) v[i]=i;
for(int i=;i<=k;i++){
d=read();x=read();y=read();
if(x>n||y>n){++ans;continue;}
if(x==y){
if(d==) ++ans;
continue;
}
ax=find(x);bx=find(x+n);cx=find(x+n*);
ay=find(y);by=find(y+n);cy=find(y+n*);
if(d==){
if(ax==by||ax==cy) ++ans;
else{v[ay]=ax;v[by]=bx;v[cy]=cx;}
}
if(d==){
if(ax==ay||ax==cy) ++ans;
else{v[by]=ax;v[cy]=bx;v[ay]=cx;}
}
}
write(ans);
return ;
}
其实这种查找元素是否在同一集合中的题(比如codevs 2597 团伙)都应该考虑一下并查集,并查集代码简单,效率又高,虽然不太容易理解。
题目来源:CODE[VS]
食物链 2001年NOI全国竞赛的更多相关文章
- Codevs 1074 食物链 2001年NOI全国竞赛
1074 食物链 2001年NOI全国竞赛 时间限制: 3 s 空间限制: 64000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description 动物王国中有三类动物 A,B ...
- 1074 食物链 2001年NOI全国竞赛
1074 食物链 2001年NOI全国竞赛 时间限制: 3 s 空间限制: 64000 KB 题目等级 : 钻石 Diamond 题目描述 Description 动物王国中有三类动物 ...
- CODEVS 1074 食物链 2001年NOI全国竞赛(洛谷 P2024)
题目描述 Description 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A吃B,B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并 ...
- Codevs 1800 假面舞会 2008年NOI全国竞赛
1800 假面舞会 2008年NOI全国竞赛 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 一年一度的假面舞会又开始了,栋栋也 ...
- 1729 单词查找树 2000年NOI全国竞赛
1729 单词查找树 2000年NOI全国竞赛 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 在进行文法分析的 ...
- 2008年NOI全国竞赛 假面舞会
/* 分三种情况 1 有环:找环长的gcd作为max gcd的超过2的最小因子作为min 2 树:所有最长链的和作为max 3为min (最长链≥3) 3 两条相交链:找出所有的这样的两条链的差 同1 ...
- 1722 最优乘车 1997年NOI全国竞赛
题目描述 Description H城是一个旅游胜地,每年都有成千上万的人前来观光.为方便游客,巴士公司在各个旅游景点及宾馆,饭店等地都设置了巴士站并开通了一些单程巴上线路.每条单程巴士线路从某个巴士 ...
- 银河英雄传说 2002年NOI全国竞赛
时间限制: 1 s 空间限制: 256000 KB 题目等级 : 大师 Master 题目描述 Description 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦创立宣言,同年 ...
- NOI全国赛(2001)--食物链
今天写了道并查集的题,看来并查集的题刷少了,,,,,用法好神奇啊!!!开三倍并查集 用i表示自己,i+n存天敌,i+2*n存可以克制de,再逻辑判断一下即可. 所以,要意识到并查集的分类处理可以开不同 ...
随机推荐
- robotframework - 基础关键词
robotframework基础关键词如下: 1.可在python.notepad++ 编辑: *** Settings *** *** Test Cases ***variable ${a} Set ...
- CSS实现居中的方式
在介绍居中方式之前,简单介绍一下行内元素和块级元素. 行内元素 和其他元素都在同一行 高,行高及外边距和内边距部分可以改变 宽度只与内容有关 行内元素只能容纳文本或者其他行内元素 常用内联元素:a,i ...
- Xml学习笔记(3)利用递归解析Xml文档添加到TreeView中
利用递归解析Xml文档添加到TreeView中 private void Form1_Load(object sender, EventArgs e) { XmlDocument doc = new ...
- python自动化--语言基础二运算符、格式化输出、条件语句、循环语句、列表、元组
运算符包括:算术运算符.比较运算符.赋值运算符.逻辑运算符.成员运算符.身份运算符. 算术运算符 % 取模(余数) // 取相除的整数部分 / (5/2=2.5) 比较运算符 == 等于 ...
- 如何把mysql的列修改成行显示数据简单实现
如何把mysql的列修改成行显示数据简单实现 创建测试表: 1: DROP TABLE IF EXISTS `test`; 2: CREATE TABLE `test` ( 3: `year` int ...
- ubuntu+ngnix+thinkphp pathinfo配置
一.thinkphp 项目改为pathinfo模式 XXX/ThinkPHP/Conf/convention.php文件中找到 'URL_MODEL' => 1, // URL访问模式,可选参数 ...
- 01Microsoft SQL Server
Microsoft SQL Server Microsoft SQL Server 是Microsoft 公司推出的关系型数据库管理系统.具有使用方便可伸缩性好与相关软件集成程度高等优点,可跨越膝上型 ...
- Django线上部署教程:腾讯云+Ubuntu+Django+Uwsgi(转载)
网站名称: 向东的笔记本 本文链接: https://www.eastnotes.com/post/29 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议.转载请注明出处! ...
- for循环,isinstance() 函数
#isinstance()的运用 #练习: 求值总和以及平均值. str_list = [1,2,3,4,5,6,'a',7,8,9,'b',10,'c'] my_tal = 0 my_var = 0 ...
- 2019西安多校联训 Day1
试题链接:http://www.accoders.com/contest.php?cid=1893 考试密码请私信; T1 明明就是O(n)的模拟,强行打成二分QAQ 思路:判断收尾是否为1或 ...