Problem E
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 176 Accepted Submission(s) : 24
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
集训队的小伙伴们每周都会打BestCoder。
BestCoder的比赛是积分制的,每打完一场比赛,就会根据你这场比赛打的情况,在你的原有分数的基础上加减分。在打了n场比赛后,每个人的rating都形成了一条优美的曲线。
这天,集训队朱队长来检查大家平日里打BestCoder的情况。队长要每个同学说自己每场比赛打完以后的加减分数和最终得分这两个数据。但是14级的同学们很调皮,他们都不按自己打的比赛的先后顺序说。有的小盆友说了谎,他们其实并没有打比赛,所以说的加减分和最终分数根本对不上。
请你帮队长看一看,到底是哪些人说了慌呢?
注:BestCoder的起始分数为1500分
BestCoder的比赛是积分制的,每打完一场比赛,就会根据你这场比赛打的情况,在你的原有分数的基础上加减分。在打了n场比赛后,每个人的rating都形成了一条优美的曲线。
这天,集训队朱队长来检查大家平日里打BestCoder的情况。队长要每个同学说自己每场比赛打完以后的加减分数和最终得分这两个数据。但是14级的同学们很调皮,他们都不按自己打的比赛的先后顺序说。有的小盆友说了谎,他们其实并没有打比赛,所以说的加减分和最终分数根本对不上。
请你帮队长看一看,到底是哪些人说了慌呢?
注:BestCoder的起始分数为1500分
Input
第一行T,表示有T组用例 T<100
每组用例第一行n,表示他一共打了n场比赛 n<1000
接下来n行,每行是+a b或者-a b,+a表示这场比赛打完加了a分,-a表示减了a分
b表示这场比赛打完的最终得分
0<a<300, b在-10000~+10000范围内
(本题rating可以出现负分)
每组用例第一行n,表示他一共打了n场比赛 n<1000
接下来n行,每行是+a b或者-a b,+a表示这场比赛打完加了a分,-a表示减了a分
b表示这场比赛打完的最终得分
0<a<300, b在-10000~+10000范围内
(本题rating可以出现负分)
Output
对于每组用例,输出一行
如果所有n场比赛能组成一条优美的曲线,输出Yes
否则输出No
如果所有n场比赛能组成一条优美的曲线,输出Yes
否则输出No
Sample Input
4 2 +15 1515 -10 1505 3 -100 1400 +10 1510 -110 1400 5 -20 1580 +20 1600 -150 1600 +150 1750 +100 1600 22 -30 1383 -87 1413 +41 1424 -20 1494 -51 1497 -89 1514 +19 1516 -48 1521 -68 1531 +17 1548 -25 1569 -36 1582 -7 1594 +105 1599 -13 1601 +179 1603 +98 1614 +97 1618 +47 1629 +59 1688 +44 1732 +17 1749
Sample Output
Yes No Yes Yes
本题由于每个数据使用顺序的不确定性,所以无法进行暴力解决
那么对于每个数据,我们可以建一条原来的数值->现在的数值的边,利用欧拉回路进行判断
#include <map> #include <set> #include <stack> #include <queue> #include <cmath> #include <ctime> #include <vector> #include <cstdio> #include <cctype> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; #define INF 0x3f3f3f3f #define inf -0x3f3f3f3f #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define mem0(a) memset(a,0,sizeof(a)) #define mem1(a) memset(a,-1,sizeof(a)) #define mem(a, b) memset(a, b, sizeof(a)) const int maxn=36010; int head[maxn],tot,in[maxn],out[maxn]; map<int,int>mp; struct Edge{ int to,next; bool flag; }e[2010]; int cnt; void init(){ tot=0; mem1(head); mem0(out); mem0(in); } void addedge(int from,int to){ e[tot].to=to; e[tot].next=head[from]; e[tot].flag=false; head[from]=tot++; } void dfs(int u){ for(int i=head[u];i!=-1;i=e[i].next){ if(!e[i].flag){ e[i].flag=true; head[u]=i; dfs(e[i].to); cnt++; } } } int main(){ int _,n; scanf("%d",&_); while(_--){ scanf("%d",&n); init(); mp.clear(); int num=0; mp[1500]=++num; int u,v,w; for(int i=1;i<=n;i++){ scanf("%d%d",&u,&v); if(mp[v]==0) mp[v]=++num; if(mp[v-u]==0) mp[v-u]=++num; out[mp[v-u]]++,in[mp[v]]++; addedge(mp[v-u],mp[v]); } int cc1=0,cc2=0; for(int i=1;i<=num;i++){ if(out[i]-in[i]==1) cc1++; else if(out[i]-in[i]==-1) cc2++; else if(out[i]-in[i]!=0) cc1=3; } if(!( (cc1==0&&cc2==0)|| (cc1==1&&cc2==1))){ printf("No\n"); continue; } cnt=0; dfs(1); if(cnt != n) printf("No\n"); else printf("Yes\n"); } return 0; }