2016SDAU课程练习四1023 Problem W
2016-07-06 23:44
281 查看
Problem W
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 48 Accepted Submission(s) : 19
[align=left]Problem Description[/align]
In 12th Zhejiang College Students Games 2007, there was a new stadium built in Zhejiang Normal University. It was a modern stadium which could hold thousands of people. The audience Seats made a circle. The total number of columns
were 300 numbered 1--300, counted clockwise, we assume the number of rows were infinite.<br>These days, Busoniya want to hold a large-scale theatrical performance in this stadium. There will be N people go there numbered 1--N. Busoniya has Reserved several
seats. To make it funny, he makes M requests for these seats: A B X, which means people numbered B must seat clockwise X distance from people numbered A. For example: A is in column 4th and X is 2, then B must in column 6th (6=4+2).<br>Now your task is to
judge weather the request is correct or not. The rule of your judgement is easy: when a new request has conflicts against the foregoing ones then we define it as incorrect, otherwise it is correct. Please find out all the incorrect requests and count them
as R.<br>
[align=left]Input[/align]
There are many test cases:<br>For every case: <br>The first line has two integer N(1<=N<=50,000), M(0<=M<=100,000),separated by a space.<br>Then M lines follow, each line has 3 integer A(1<=A<=N), B(1<=B<=N), X(0<=X<300) (A!=B), separated
by a space.<br><br>
[align=left]Output[/align]
For every case: <br>Output R, represents the number of incorrect request.<br>
[align=left]Sample Input[/align]
10 10
1 2 150
3 4 200
1 5 270
2 6 200
6 5 80
4 7 150
8 9 100
4 8 50
1 7 100
9 2 100
[align=left]Sample Output[/align]
题目大意:
有n个人坐在zjnu体育馆里面,然后给出m个他们之间的距离, A B X, 代表B的座位比A多X. 然后求出这m个关系之间有多少个错误,所谓错误就是当前这个关系与之前的有冲突。
分析与总结:
题目有一句话:we assume the number of rows were infinite. 就是假设这个体育馆是无限大的,所以不用考虑圆圈循环的情况。
用带权并查集做, 对于并查集中的每一棵数, 树根的距离为0,然后以树根作为参照,每个结点的权值代表与树根的距离。
合并A,B时,假设A,B属于不同的树,那么就要合并这两棵树, 把A树合并到B树上,这时要给A树的跟结点root_a赋值,关键是给root_a附上一个什么值。 由于A点和B点的权值rank[A]和rank[B]都是相对跟结点的距离,所以分析A,B之间的相对距离,可以得到rank[root_a] = rank[A]+x-rank[B]。 注意到这时,对于原来的A的树,只跟新了root_a跟结点的权值, 那么其它结点的跟新在查找的那一步里面实行了。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
#include<math.h>
using namespace std;
typedef long long ll;
//typedef __int64 int64;
const int maxn = 50015;
const int inf = 0x7fffffff;
const double pi=acos(-1.0);
const double eps = 1e-8;
int dis[ maxn ],fa[ maxn ];
void init( int n ){
for( int i=0;i<=n;i++ ){
dis[ i ] = 0;
fa[ i ] = i;
}
return ;
}
int find( int x ){
if( fa[x]==x ) return x;
int tmp = find( fa[x] );
dis[ x ] = dis[ x ]+dis[ fa[x] ];
dis[ x ] = dis[ x ]%300;
fa[ x ] = tmp;
return fa[ x ];
}
bool unionab( int a,int b,int c ){
int x = find(a);
int y = find(b);
//printf("fa[%d]=%d,fa[%d]=%d,dis[%d]=%d,dis[%d]=%d\n",a,x,b,y,a,dis[a],b,dis[b]);
if( x==y ){
if( ((dis[b]-dis[a]+300)%300)!=c ){//b在a的后面,保证是dis[b]-dis[a]
//printf("test:%d %d\n",a,b);
return false;
}
}
else{
dis[ y ] = dis[ a ]+c-dis[ b ]+300;
dis[y] %= 300;
fa[ y ] = x;
}
return true;
}
int main(){
int n,m;
while( scanf("%d%d",&n,&m)==2 ){
int a,b,c;
init( n );
int res = 0;
while( m-- ){
scanf("%d%d%d",&a,&b,&c);
bool f = unionab( a,b,c );
if( f==false ) res++;
}
printf("%d\n",res);
}
return 0;
}
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 48 Accepted Submission(s) : 19
[align=left]Problem Description[/align]
In 12th Zhejiang College Students Games 2007, there was a new stadium built in Zhejiang Normal University. It was a modern stadium which could hold thousands of people. The audience Seats made a circle. The total number of columns
were 300 numbered 1--300, counted clockwise, we assume the number of rows were infinite.<br>These days, Busoniya want to hold a large-scale theatrical performance in this stadium. There will be N people go there numbered 1--N. Busoniya has Reserved several
seats. To make it funny, he makes M requests for these seats: A B X, which means people numbered B must seat clockwise X distance from people numbered A. For example: A is in column 4th and X is 2, then B must in column 6th (6=4+2).<br>Now your task is to
judge weather the request is correct or not. The rule of your judgement is easy: when a new request has conflicts against the foregoing ones then we define it as incorrect, otherwise it is correct. Please find out all the incorrect requests and count them
as R.<br>
[align=left]Input[/align]
There are many test cases:<br>For every case: <br>The first line has two integer N(1<=N<=50,000), M(0<=M<=100,000),separated by a space.<br>Then M lines follow, each line has 3 integer A(1<=A<=N), B(1<=B<=N), X(0<=X<300) (A!=B), separated
by a space.<br><br>
[align=left]Output[/align]
For every case: <br>Output R, represents the number of incorrect request.<br>
[align=left]Sample Input[/align]
10 10
1 2 150
3 4 200
1 5 270
2 6 200
6 5 80
4 7 150
8 9 100
4 8 50
1 7 100
9 2 100
[align=left]Sample Output[/align]
2 <div style='font-family:Times New Roman;font-size:14px;background-color:F4FBFF;border:#B7CBFF 1px dashed;padding:6px'><div style='font-family:Arial;font-weight:bold;color:#7CA9ED;border-bottom:#B7CBFF 1px dashed'><i>Hint</i></div> Hint: (PS: the 5th and 10th requests are incorrect) </div>
题目大意:
有n个人坐在zjnu体育馆里面,然后给出m个他们之间的距离, A B X, 代表B的座位比A多X. 然后求出这m个关系之间有多少个错误,所谓错误就是当前这个关系与之前的有冲突。
分析与总结:
题目有一句话:we assume the number of rows were infinite. 就是假设这个体育馆是无限大的,所以不用考虑圆圈循环的情况。
用带权并查集做, 对于并查集中的每一棵数, 树根的距离为0,然后以树根作为参照,每个结点的权值代表与树根的距离。
合并A,B时,假设A,B属于不同的树,那么就要合并这两棵树, 把A树合并到B树上,这时要给A树的跟结点root_a赋值,关键是给root_a附上一个什么值。 由于A点和B点的权值rank[A]和rank[B]都是相对跟结点的距离,所以分析A,B之间的相对距离,可以得到rank[root_a] = rank[A]+x-rank[B]。 注意到这时,对于原来的A的树,只跟新了root_a跟结点的权值, 那么其它结点的跟新在查找的那一步里面实行了。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
#include<math.h>
using namespace std;
typedef long long ll;
//typedef __int64 int64;
const int maxn = 50015;
const int inf = 0x7fffffff;
const double pi=acos(-1.0);
const double eps = 1e-8;
int dis[ maxn ],fa[ maxn ];
void init( int n ){
for( int i=0;i<=n;i++ ){
dis[ i ] = 0;
fa[ i ] = i;
}
return ;
}
int find( int x ){
if( fa[x]==x ) return x;
int tmp = find( fa[x] );
dis[ x ] = dis[ x ]+dis[ fa[x] ];
dis[ x ] = dis[ x ]%300;
fa[ x ] = tmp;
return fa[ x ];
}
bool unionab( int a,int b,int c ){
int x = find(a);
int y = find(b);
//printf("fa[%d]=%d,fa[%d]=%d,dis[%d]=%d,dis[%d]=%d\n",a,x,b,y,a,dis[a],b,dis[b]);
if( x==y ){
if( ((dis[b]-dis[a]+300)%300)!=c ){//b在a的后面,保证是dis[b]-dis[a]
//printf("test:%d %d\n",a,b);
return false;
}
}
else{
dis[ y ] = dis[ a ]+c-dis[ b ]+300;
dis[y] %= 300;
fa[ y ] = x;
}
return true;
}
int main(){
int n,m;
while( scanf("%d%d",&n,&m)==2 ){
int a,b,c;
init( n );
int res = 0;
while( m-- ){
scanf("%d%d%d",&a,&b,&c);
bool f = unionab( a,b,c );
if( f==false ) res++;
}
printf("%d\n",res);
}
return 0;
}
相关文章推荐
- LeetCode 70
- github版本回退
- 快排算法
- csr8670--button按键的实现
- 学习笔记-Java中的xml文件读取之DOM4J解析
- android ContentObserver,BroadcastReceiver,Handler各自用法
- python开发环境PyCharm安转注册
- [C/C++] printf函数用法详解
- android的四种启动模式
- [转载]EasyDarwin手机直播是如何实现的快速显示视频的方法
- 专题四--1002
- 专题四--1001
- 西工大空院电子信息工程本科主干课程回顾总结
- TCP和UDP通信
- csr8670--sink工程的大致工作流程分析(以speaker为例)二
- Web 数据实时收集入Hbase ,通过Hive 分析 (JS SDK)
- 微信获取code和openid
- 记一次开发:Qt简单电话本程序
- BZOJ1795 : [Ioi2008]Pyramid Base 金字塔地基
- HTML学习笔记(下)