GDUFS 2017信息学院程序设计新手赛(正式赛)题解

紧张刺激的新手赛结束了……有惊无险啊啊啊,虽然中途OJ炸了一次……很快就修复,感谢大家耐心的等待!一开始有的教室环境没装好,也感谢大家耐心的等待下载……毕竟我校第一次除了考试,搞这么大型的ACM比赛……


谢谢大家!!!


题解开始前,先向大家道个歉,题目还是很多误导人的地方,卡的点较多,导致很多人题没过。接下来都会一一解释……希望大家能理解……不过题目区分度还是达到了预期,有的同学表现也很抢眼。



Problem A: 叉叉哥哥的童年

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 1429   Solved: 306

Description

故事在一片以橘黄色为基调的暖色中展开:典型的南方麻石小巷,橘灯摇曳、晃悠,一个悠远的曲巷深处传来悠长的叫卖声:“黑--芝麻糊哎—”,一个戴着棉帽穿着布衫的少年推门探出头来,不停地搓手、呵气,眼中充满渴望;小担那头慈祥的大婶正把一大勺浓稠的黑芝麻糊舀向碗里,男孩急不可耐地搓手、咬唇,一副“小馋猫”的模样。当大婶把香浓的黑芝麻糊递给小男孩后,他迫不及待大口大口地吃,吃完以后把碗底也舔得干干净净,引得一旁碾磨芝麻的小女孩掩嘴窃笑,但他依然痴痴地贪婪地望着锅中的黑芝麻糊。慈祥的老板娘充满爱怜地摸摸孩子的头,又把满满的一勺黑芝麻糊舀到孩子的碗中。他,就是叉叉哥哥,一位传奇少年。他从小就爱吃芝麻糊,长大了也一样。今天叉叉哥哥又冲了一袋芝麻糊吃了。已知黑芝麻芝麻糊一袋重N克,用M克热水去冲泡,用重K克的碗去装,请问,最后得到的芝麻糊包括碗,有多重?

Input

只有一行,包括3个数字,分别为N,M,K,中间用空格隔开,其中 (1<=N,M,K<=1000

Output

一个数字即最后的重量。(忽略各种化学变化与物理变化,排除所有外界干扰)

Sample Input

1 2 3

Sample Output

6.00

HINT


输出保留两位小数



题目定位:签到题,难度系数 1(满分10分)


题解:保留两位小数。这里是采用直接丢弃两位后面的位……不是四舍五入……JAVA的同学要注意……另外输入的A,B,C有可能是小数!所以要用double 存!不要用int!否则会错!


标程:

#include
using namespace std;


int main(){

    double a,b,c;
    cin>>a>>b>>c;
    printf("%.2lf\n",a+b+c);

    return 0;
}




Problem B: 叉叉哥哥的数学课

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 962   Solved: 111

Description

终于叉叉哥哥长大了,在小学连跳三级的他,已经在研究行列式了,行列式是多么的优美呀!我们知道一个二阶行列式可以表示为

W X

Y Z

其中WXYZ为四个数字,二阶行列式的计算公式为 W*Z-Y*X。现在我们给二阶行列式的四个数字编号,分别为

1 2

3 4

刚好叉叉哥哥最近也在学习解方程,于是他想考考你们,当已知二阶行列式的值时,求二阶行列式中的一个未知数的值。

Input

输入包括四行。

第一行为一个整数K,代表行列式的值。(-10000<=K<=10000

第二到四行,每行两个整数Xi,Yi,代表编号为Xi的数字为Yi1<=Xi<=4)(-10000<=Yi<=10000Yi<>0),数据保证没有重复的Xi

Output

输出包括两个数字X,Y。其中X代表该行列式中的未知数的编号,Y为该未知数的值。

Sample Input

-2
2 3
3 -2
4 4

Sample Output

1 -2.00

HINT


输出的Y保留两位小数


注意数据范围!请使用long long int或double保存所有变量





题目定位:简单题,难度系数 3


题解:保留两位小数。注意!出现了除法运算!就必须要用double !如果变量用int存,运算完毕后,还是int,这就不对了,我们需要在运算的过程中强制转换为double,或者直接用double来保存变量。其他的,自己思考怎么实现了,毕竟行列式公式也给了,剩下的就是逻辑问题。具体看代码。


标程:

#include
using namespace std;


int main(){

    double K;
    

        double zs,zx,ys,yx;

        int a=0,b=0,c=0;
        int weizhi=10;

        cin>>a;
        if(a==1)cin>>zs;
        if(a==2)cin>>ys;
        if(a==3)cin>>zx;
        if(a==4)cin>>yx;

        cin>>b;
        if(b==1)cin>>zs;
        if(b==2)cin>>ys;
        if(b==3)cin>>zx;
        if(b==4)cin>>yx;

        cin>>c;
        if(c==1)cin>>zs;
        if(c==2)cin>>ys;
        if(c==3)cin>>zx;
        if(c==4)cin>>yx;

        weizhi-=a+b+c;

        if(weizhi==1){
            zs=(K+zx*ys)/yx;
            printf("%d %.2lf\n",weizhi,zs);
        }

        if(weizhi==2){
            ys=(zs*yx-K)/zx;
            printf("%d %.2lf\n",weizhi,ys);
        }

        if(weizhi==3){
            zx=(zs*yx-K)/ys;
            printf("%d %.2lf\n",weizhi,zx);
        }

        if(weizhi==4){
            yx=(K+zx*ys)/zs;
            printf("%d %.2lf\n",weizhi,yx);
        }

        //cout<




Problem C: 叉叉哥哥的游戏

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 1401   Solved: 148

Description

一转眼,叉叉哥哥又长大了几岁,最近他迷上一款游戏。叫绝地求生。绝地求生(Playerunknown's Battlegrounds),俗称吃鸡,是Bluehole公司与《H1Z1》、《武装突袭3》“大逃杀”模式制作人Playerunknown联合开发的第一人称射击游戏,采用虚幻4引擎制作。这款游戏是一款大逃杀类型的游戏,每一局游戏将有最100名玩家参与,他们将被投放在绝地岛(battlegrounds)上,在游戏的开始时所有人都一无所有。玩家需要在岛上收集各种资源,在不断缩小的圆形安全区域内对抗其他玩家(在安全区外的会死亡),让自己生存到最后。本作拥有很高的自由度,玩家可以体验飞机跳伞、开越野车、丛林射击、抢夺战利品等玩法,小心四周埋伏的敌人,尽可能成为最后1个存活的人。但是叉叉哥哥枪法实在是太差了,从未“吃鸡”,被迫无奈,他只好借助高科技了。通过高科技,叉叉哥哥可以看到每一位玩家的坐标了,现在他想知道,当前在安全区中的玩家有多少个。(如果玩家在安全区的边界,也算在安全区内,地图中心的坐标为(0,0))

Input

输入包括多行。

第一行为三个整数X,Y,R,代表安全区中心的坐标和安全区的半径。(-100000<=X,Y,R<=100000

第二行为一个整数N,代表该场游戏有N名玩家参与(1<=N<=100

接下来 行,每行两个整数Xi,Yi,代表第i名玩家的坐标(-100000<=Xi,Yi<=100000)(1<=i<=N

Output

输出一个整数,代表有多少个玩家在安全区内。(假设地图无限大)

Sample Input

0 0 10
3
10 0
0 10
10 10

Sample Output

2

HINT

数据范围较大


请使用 double或long long int


long int 为32位


long long int 为64位



题目定位:简单题2,难度系数 3


题解:……直接求点到圆心的距离,看看是不是小于R即可~这里没想到卡住了那么多人。首先,int * int会爆int,所以我们要强制转换成long long去运算。比如 100000*100000=100000000000(已经超过了int的范围,实际上不是这个值)。如果还不能理解,请复习C++基础……另外如果用double去运算会失去精度,因为计算机的浮点数运算是有误差的。比如你觉得  6==6,但其实不一定,可能是  6.000001!=6。为了避免精度问题,我们不能使用系统的开方函数。sqrt返回的是double,参数也是double,所以传long long 的话也有可能会失去精度,所以最好的做法,就是直接用long long去运算。详细看代码。


标程:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long int ll;
int main(){
    long long int X,Y,R;
    cin>>X>>Y>>R;
        int n;
        cin>>n;
        int ans=0;
        while(n--){
            long long int a,b;
            cin>>a>>b;
            if((a-X)*(a-X)+(b-Y)*(b-Y)<=R*R)
                ans++;


        }
        cout<



Problem D: 叉叉哥哥的金鱼

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 633   Solved: 51

Description

多年以后,叉叉哥哥站在大海面前,想起他第一次钓鱼的那个遥远的下午。当时,有n0<=n<=1000)只不幸运的鱼已经笨拙的叉叉哥哥钓了上来,

但是叉叉哥哥对着这些鱼犯难了,假如将这些鱼一起放入鱼缸的话,体积相对小的鱼就会被体积比它大的鱼吃掉!但是体积相对小的鱼并不能吃掉体积比它大的鱼。然而傻傻的叉叉哥哥别无他法,只能选择将那些鱼全部放入鱼缸,据叉叉哥哥观察这些鱼有一个特性,它们只会吃一条比自己小的鱼,然后宁愿饿到昏迷也不会再去吃其他鱼,比如鱼缸中有三条鱼体积分别为3, 3,那么体积为5的鱼只会吃一条体积为3的鱼,然后鱼缸中剩下两条鱼,一条体积为5,另一条为3。值得注意的是,一条鱼吃了其他鱼之后它的体积并不会变化。可能是能量都消耗在吃鱼的过程中了,叉叉哥哥猜。

你可以帮叉叉哥哥算出最坏情况下鱼缸里会剩几条鱼吗?(注意:体积相等的两条鱼都吃不了对方)

Input

一个整数n代表鱼的数量(0<=n<=1000

后面n行,每行一个整数t0<=t<=1000000000)代表每只鱼的体积


Input1:

5

1

2

3

4

5


Input2:

3

10000000

10000000

10000000

Output

一个整数,代表最坏情况下鱼缸中剩下的鱼的数量

Output1

1

Output2:

3

Sample Input

5
1
2
3
4
5

Sample Output

1

HINT


对于第一个样例


1->2->3->4->5,‘XX->YY'代表XXYY吃掉)


对于第二个样例


(谁也吃不掉其他鱼)




题目定位:简单题里面的难题,难度系数 4


题解:这道题开始就考思维了。想到的话,这道题就很简单了。实际上就是求一堆数里的众数的大小!……为什么呢?因为求的是最坏情况,所以肯定是次小的吃掉最小的,然然然后次次小的,吃掉次小的,这样贪心的去吃。你会发现,最后剩下的,就是众数的大小。相当于不同的鱼之间,可以合体,这里的思维很巧妙…自己写多几组样例应该能推出来。标程用了高级的数据结构,实际上这里可以用排序或者结构体去做。


标程:

#include 
#include 
using namespace std;
const int MAX_N=1005;
int temp,n,ans;
map m;//映射减小数组开销 
int main()
{
	m.clear();
	ans=0;
	cin>>n;
	for(int i=0;i>temp;
		ans=max(ans,++m[temp]);
	}
	cout<


Problem E: 叉叉哥哥的时光机

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 352   Solved: 1

Description

随着时间一长,一言难尽的事情越来越多,叉叉哥哥最近回想起过去,他觉得生活变得越来越糟,时间也变得越来越快,就连天气都越来越冷了,Alice十分同情叉叉哥哥,她决定将自己的时光机器借给叉叉哥哥使用,但是她的时光机器只能使用一次,这意味着叉叉哥哥只能回到一个时间点去感受快乐,但世界总是告诉我们凡事都有利弊,叉叉哥哥深明这点,他决定给所有时间轴上的事件一个不愉快值,对于每个事件,不愉悦度=|当前所在时间点-事件发生时间点|*该事件的不愉悦值,这意味这叉叉哥哥回到了任意一个时间点时,在这之前发生的事件和在这之后发生的事件都会增加他的不愉悦度,你可以帮叉叉哥哥找出他应该回到时间轴上的哪个点从而得到最小的不愉悦度之和吗?(|XX|代表XX的绝对值,时间轴上的点坐标可为负数)

Input

第一行:一个整数n2<=n<=10000)代表事件的个数

2 - n+1行:每行两个数,中间用空格分隔,分别是事件发生的时间以及该事件的不愉快值(-10^5 <= X[i] <= 10^51 <= W[i] <= 10^5

Output

输出最小的不愉悦度之和。

Sample Input

5
-1 1
-3 1
0 1
7 1
9 1

Sample Output

20

HINT


对于样例,如果用时光机跳回0点,得到的不愉悦度和为 1*1+3*1+0*1+7*1*9*1=20


注意数据范围!请使用long long int!



题目定位:难题,难度系数 9


题解:嗯,就一个大佬做出来,不知道为什么这么多人死磕这道题,其实还有很多简单题的……但这道题并不是最难的,这告诉我们,不要盲目跟榜。高难度的思维题,注意分析时间复杂度。

考虑暴力,复杂度O(n^2)明显不可行 
第一种思路 
在x轴上从左到右枚举,先暴力算出第一个点到所有点的带权距离之和,而后每一个点到其他所有点的带权距离可由前一个点的距离推出
复杂度为O(nlogn+n);
第二种思路
权值可以考虑成有w[i]个这样的点在X轴上,求最中心那个点到所有点的距离之和 
注意int类型会溢出,请使用long long。 


标程:

#include 
#define ll long long 
using namespace std;
const int MAX_N=1e4+10;
struct Node
{
	int x,w;
}node[MAX_N];
bool cmp(Node a,Node b)
{
	return a.x==b.x?a.w<=b.w:a.x



Problem F: 叉叉哥哥的爱丽丝

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 428   Solved: 34

Description

叉叉哥哥最近喜欢上的了一个女孩子,她的名字叫做Alice,他很喜欢和Alice玩耍~

Alice最近迷上了捉迷藏,但是机智的叉叉哥哥已经识破了她的小伎俩。

现在叉叉哥哥告诉你Alice小伎俩的信息,你可以帮助叉叉哥哥抓住Alice吗?

整个地图可视为一维平面,用x轴来表示(1<=x<=100

叉叉哥哥会给你提供n0<=n<=100)个信息,每个信息包含两个整数LR1<=L,R<=100,代表Alice可能藏身在LR区间中的任一点。

当所有区间拥有至少一个共同点时,我们就可以认为根据叉叉哥哥的信息找到了Alice藏身的位置即所有区间的相交区间(可能是一个点),否则我们可以判定Alice是藏身在草丛中。

Input

一个整数 n0<=n<=100

后面有n

每行两个整数LR1<=L,R<=100)代表叉叉哥哥可能藏身在LR区间中的任一点。

Output

如果可以找到叉叉哥哥的可能藏身位置,就输出“XXgg is Hide On ‘pos’”(不要双引号)其中‘pos’代表叉叉哥哥可能藏身的位置中x坐标最小的点的坐标,例如:XXgg is Hide On 1XXgg is Hide On 2

否则输出“XXgg is Hide On Bush”(不要双引号)

Output

如果可以找到叉叉哥哥的可能藏身位置,就输出“XXgg is Hide On ‘pos’”(不要双引号)其中‘pos’代表叉叉哥哥可能藏身的位置中x坐标最小的点的坐标,例如:XXgg is Hide On 1XXgg is Hide On 2

否则输出“XXgg is Hide On Bush”(不要双引号)

Sample Input

1
1 100

Sample Output

XXgg is Hide On 1

HINT


因为只有一个区间,则这整个区间都可能是叉叉哥哥的藏身处,我们只需输出x坐标最小一点的坐标,即1




题目定位:中等题,难度系数 6


题解:数据很小,怎么做都行,重点是能不能想出怎么做……题目描述有点小问题(到底谁抓谁?),比赛时没人问,不过不影响做题……这道题默认排好序,不过不影响做题……

数据量只有100 ,暴力可行,找出所有线段的相交点可以使用枚举来实现O(n^2)复杂度可以接受
考虑优化,可以对存储l,r值的结构体进行按l的值从小到大,假如l相等则r从小到大进行排序,之后看是否所有r都小于或等于node【0】.l;复杂度O(logn)
对于此类问题可以用前缀和进行进一步优化,对与每一对l,r,使a[l]=a[l]+1,a[r+1]=a[r]-1;然后通过a[i]+=a[i-1]求出每个点被覆盖了多少次,假如a[i]==n则i满足条件;


标程:

#include 
using namespace std;
const int MAX_N=105;
int n,l,r,a[MAX_N];
int main()
{
	memset(a,0,sizeof(a));
	scanf("%d",&n);
	for(int i=0;i0)
	for(int i=1;i<=100;i++)
	{
		a[i]+=a[i-1];
		if(a[i]==n)
		{
			printf("XXgg is Hide On %d\n",i);
			return 0;
		}
	}
	puts("XXgg is Hide On Bush");
	return 0;
}



Problem G: 叉叉哥哥的菜肴

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 17   Solved: 1

Description

最近叉叉哥哥在学做菜~马上食神大赛就开始啦!这次食神大赛的规则是,看谁做出的一日三餐的种类最多!一日包括三餐,分别是早餐,午餐和晚餐。叉叉哥哥为这一日三餐准备了各种各种的菜式!当然有一些菜式不能一起吃!每一种菜式由各种调料组成,当然,调料也有很多种牌子,每一种牌子都有它的特点。所以使用不同的牌子的调料去做菜,会使得菜的味道变得不一样。我们把味道不一样的菜视为不同的菜。一些常用的调料会被广泛的应用在各种菜上,比如说盐。这个时候,我们所有用了盐的菜,都会使用同一个牌子的盐(只要一种调料被用了多次,那么所有用了这个调料的菜都会使用一个牌子的调料)。现在叉叉哥哥想知道,通过不同菜式的搭配和调料的搭配,他能制造出多少种不同的一日三餐?

Input

输入包括多行

第一行包括5个整数

R,S,M,D,N,中间用空格隔开 (1<=R,S,M,D,N<=10

其中,R代表这个世界上有多少种调料。

S,M,D分别代表早餐,中餐,晚餐,有多少种菜可以选择

N代表有多少对菜式不能在一日一起吃。

第二行包括R个整数Bi1<=i<=R),代表第i种调料有Bi种牌子。第i种调料的编号为i1<=Bi<=10

接下来按顺序共S+M+D行,先是S行,后M行,后D行,从现在开始,第几行就是该菜的编号。

每行第一个数字为K,代表该菜式由K种调料组成(所有调料必须用上)接下来K个数字Ii代表该调料的编号。(1<=K,Ii<=10)

接下来N行,每行两个编号X,Y,代表哪两个菜不能一起吃。数据保证不会出现重复的对。(1<=X,Y<=10)

输入样例1

6 1 1 1 0

2 3 1 5 3 2

2 1 2

3 3 4 5

1 6

输入样例 2

3 2 2 1 1

2 3 2

1 1

1 2

1 2

1 3

1 1

2 3

输入样例3

3 1 1 1 1

5 5 5

3 1 2 3

3 1 2 3

3 1 2 3

2 1

Output

一个数字即叉叉哥哥能做出多少种不同的一日三餐!

输出样例1

180

输出样例 2

22

输出样例3

0

Sample Input

3  2  2  1  1
2  3  2
1  1 
1  2 
1  2 
1  3 
1  1 
2  3

Sample Output

22

HINT


对于输入样例。早中晚各有一种菜


有六种调料,每种有2 3 1 5 3 2个牌子


然后


早餐的一个菜,的调料有 1 2号 (该菜为1号菜)


中餐的一个菜的调料 有 3 4 5 号 (该菜为2号菜)


晚餐的一个菜的调料有 号 (按顺序,该菜为3号菜)


所以一日三餐的的种类一共有


2 * 3 * 1 * 5 * 3 * 2 =180



对于第二个样例


注意有的菜用了同一种调料,所以那种调料只能用同一个牌子。



对于第三个样例


因为 2号菜和1号菜不能在一日内一起吃,所以一种都做不出。




题目定位:中等题中的简单题,难度系数 5


题解:这道题让我很意外……因为……这是一道简单题啊……现场竟然只有一个交,而且还是绝杀!只是描述很长,让大家感觉是难题……但相信我,真的是简单题……处理的时候,循环比较多而已。原题是一道英文题,而且数据很大,卡了long double的精度。这里把数据范围缩小到10以内。随便做都可以。

原题链接:http://blog.csdn.net/lzc504603913/article/details/78185185


怎么做呢?答案就是,把所有用到的调料的牌子数相乘即可!!中间注意要把不能一起吃的菜排除,这里用二维数组记录即可!还有出现过相同的调料,直接把牌子数变成1或者不乘即可!这里标程用set去做了。


权哥的代码:

#include 
#include 
#include 
using namespace std;
int main()
{
    int R,S,M,D,N,i,j,k;
    long long s[15][15],m[15][15],d[15][15],b[15]; 
    bool tr[105][105];
    cin >> R >> S>>M>>D>>N;
    for (i=1;i<=R;i++)
    {
        cin >> b[i];
    }
    long long ans=0;
    for (i=1;i<=S;i++)
    {
        cin >> s[i][0];
        for (j=1;j<=s[i][0];j++)
        {
            cin >> s[i][j];
        }
    }
    for (i=1;i<=M;i++)
    {
        cin >> m[i][0];
        for (j=1;j<=m[i][0];j++)
        {
            cin >> m[i][j];
        }
    }
    for (i=1;i<=D;i++)
    {
        cin >> d[i][0];
        for (j=1;j<=d[i][0];j++)
        {
            cin >> d[i][j];
        }
    }
    memset(tr,true,sizeof(tr));
    for (i=1;i<=N;i++)
    {
        cin >> j >> k;
        tr[j][k]=false;
        tr[k][j]=false;
    }
    int i1,i2,i3,er;
    bool w;
    bool t[15];
    ans=0;
    for (i1=1;i1<=S;i1++)
        for (i2=1;i2<=M;i2++)
            for (i3=1;i3<=D;i3++)
            {
                memset (t,false,sizeof(t));
                if (tr[i1][i2+S]&&tr[i1][i3+S+M]&&tr[i2+S][i3+M+S])
                {
                    for (i=1;i<=s[i1][0];i++)
                        t[s[i1][i]]=true;
                    for (i=1;i<=m[i2][0];i++)
                        t[m[i2][i]]=true;
                    for (i=1;i<=d[i3][0];i++)
                        t[d[i3][i]]=true;
                    er=1;
                    w=false;
                    for (i=1;i<=R;i++)
                        if (t[i])
                        {
                            er*=b[i];
                            w=true;
                        }
                    if (w)
                        ans+=er;
                }
            }
    cout << ans;
}

标程:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long int ll;
 
int r,s,m,d,n;
 
ll brand[105000];
vector ingre[10000];
 
int no[100][100];
 
 
int main()
{
 
 
    memset(no,0,sizeof(no));
    scanf("%d%d%d%d%d",&r,&s,&m,&d,&n);
    int temp;
    for(int i=1;i<=r;i++){
        scanf("%lld",&temp);
        brand[i]=temp;
    }
 
    int k;
    for(int i=1;i<=s+m+d;i++){
 
        scanf("%d",&k);
        for(int j=1;j<=k;j++){
            scanf("%d",&temp);
            ingre[i].push_back(temp);
        }
 
    }
    int a,b;
    for(int i=1;i<=n;i++){
        scanf("%d%d",&a,&b);
        no[a][b]=1;
        no[b][a]=1;
    }
 
 
    ll ans=0;
    for(int i=1;i<=s;i++){
        for(int j=s+1;j<=s+m;j++){
 
            if(no[i][j])
                continue;
 
            for(int k=s+m+1;k<=s+m+d;k++){
                if(no[j][k])
                    continue;
                if(no[i][k])
                    continue;
 
                set ss;
                for(int q=0;q::iterator it=ss.begin();it!=ss.end();it++){
 
                    tt*=brand[(*it)];
 
                }
 
                ans+=tt;
 
 
 
            }
        }
    }
 
 
 
        cout<


Problem H: 叉叉哥哥的脱口秀

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 27   Solved: 0

Description

一眨眼,叉叉哥哥来到了老年时期了。回想当年,曾经是多么的辉煌。叉叉哥哥,曾经是一个演员。他经常参与演出两种剧,参与这两种剧都会影响他的魅力值。这两种剧分别是喜剧和悲剧。叉叉哥哥只擅长演喜剧。所以当叉叉哥哥拍完喜剧后,他的魅力值会上升A,当拍完一场悲剧后,他的魅力值会减去B(叉叉哥哥演悲剧总会笑……)。叉叉哥哥又很喜欢参加脱口秀节目!脱口秀节目会使他的人气值大大改变!具体的,当他参加完脱口秀后,再去演喜剧,他的魅力值会增加C而不是A,如果演的是悲剧,他的魅力值会减少D而不是B(因为他笑的更厉害了)。叉叉哥哥很喜欢参加脱口秀,但是他又不想自己的魅力值变成负数,所以他想找个一个合适的时间点去参加脱口秀,使得自己的魅力值不会变成负数。

我们假设叉叉哥哥的演员生涯开始的时间为0,在那个时候,叉叉哥哥的魅力值为S,如果叉叉哥哥在T时间参加了脱口秀,那么这个脱口秀会影响接下来的这个时间区间[T,T+LEN )内的所有演出(即ACBD,注意开闭区间)。其中LEN为这个脱口秀的影响时间长度。叉叉哥哥真的很想参加脱口秀,但他不想自己的魅力值在参加脱口秀前变为负数,又不想在参加脱口秀后的LEN时间内自己的魅力值变为负,当然过后就没所谓了。现在他告诉你他的行程表,请你帮帮他,找到一个最好的时间,去参加脱口秀。叉叉哥哥很喜欢演戏,所以每一部戏他都会参与演出,无论魅力值怎么样。注意,每个整数时间点都有一场脱口秀,但叉叉哥哥只能参加一场脱口秀。参加完脱口秀后,叉叉哥哥可以马上去演戏。

Input

输入包括多行。

第一行包括7个正整数,中间用空格隔开,分别为

N A B C D S LEN 1<=N<=300000,0<=S<=10^9,1<=A,B,C,D,LEN<=10^9

其中N为已知的戏的数量.

接下来N行,每行包括两个整数Ti,Qi 1<=Ti<=10^9,0<=q<=1

其中Ti为演出的戏的时间点,q为戏的类型,1代表喜剧,0代表悲剧。

其中Ti会以升序给出,并保证所有的Ti都不一样。

输入样例1

5 1 1 1 4 0 5
1 1
2 1
3 1
4 0
5 0

输入样例2

1 1 2 1 2 1 2
1 0

输入样例3

10 1 1 1 2 0 10

1 1

2 1

3 0

4 0

5 1

6 1

7 1

8 1

9 1

10 1

Output

输出包括一个整数。代表参加脱口秀的时间点。如果有多个时间可选,输出最小的。如果没有时间点符合题目要求,输出-1.

输出样例1

6

输出样例2

-1

输出样例3

5

Sample Input

10 1 1 1 2 0 10
1 1
2 1
3 0
4 0
5 1
6 1
7 1
8 1
9 1
10 1

Sample Output

5

HINT


对于第一个样例


只能在参加完所有戏后,参加脱口秀。否则肯定会有个时间点魅力值变为负。


对于第二个样例


无论在哪个时间点参加脱口秀,都会在参加脱口秀之前或中间魅力值变为负。


对于第三个样例


5之后参加脱口秀都是可以的,但5是最小的一个。


假设在4参加。那么他的魅力值变化为


0 -> 1 -> 2 ->1 -> -1


所以不行,最小就是5



题目定位:防AK题,即最难题,难度系数 10


题解:这道题真防AK……但是还是没有考算法……还是考思维,这题很容易让人陷入二分,然后会调半天,二分应该是不能做的,至少我没有用二分做出来。最后用了尺取法,尺取法是一种思维的方法,可以大大降低复杂度。详细看原题的解释……

原题链接:http://blog.csdn.net/lzc504603913/article/details/78481915


标程:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long int ll;

struct act{
    ll time;
    int type;
}list[300005];

int main(){

    ll n,a,b,c,d,start,len;
    scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&a,&b,&c,&d,&start,&len);

    for(int i=1;i<=n;i++)
        scanf("%lld%d",&list[i].time,&list[i].type);

    list[0].time=-1;
    int j=1;
    ll qrank=start;
    ll hrank=0;
    ll hmin=0;

    for(int i=1;i<=n;i++){

        for(;j<=n;j++){
            if(list[j].time-list[i].time>len)
                break;
            if(list[j].type)
                hrank+=c;
            else
                hrank-=d;

            hmin=min(hmin,hrank);
        }
        if(qrank>=-hmin){

            cout<




Problem I: 叉叉哥哥的藏身处

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 349   Solved: 122

Description

叉叉哥哥最近迷上了捉迷藏,但是机智的Alice已经知道了他喜欢藏哪了!

现在Alice告诉你叉叉哥哥的信息,你可以帮助Alice抓住叉叉哥哥吗?

整个地图可视为一维平面,用x轴来表示(1<=x<=1000),据Alice透露,叉叉哥哥每次藏身的位置的坐标都是一个质数,而且她会给你提供叉叉哥哥所在的质数是第几小的质数,

但是调皮的Alice有时候会故意撒谎,当她所提供的数K大于1000以内的质数个数时输出“NOT FOUND”(不要引号),否则输出x轴上第K小的质数

Input

一个整数 k1<=k<=10^9

Output

如果k合法时则输出第k小的质数,否则输出“NOT FOUND”(不要引号)

如输入

200

输出

NOT FOUND

Sample Input

1

Sample Output

2

HINT


一个数如果他的因数只有1和他本身,那么它就是质数




题目定位:中等题里的简单题,难度系数 6


题解:考察了质数的概念,这里数据范围很小,O(N^2)筛选质数也是可以的~!其他的就是读题啦!!很多人没搞懂提议,所以没做出来。这里还是自己想懂比较好。


标程:

#include 
using namespace std;
const int MAX_N=1005;
int a[MAX_N],cnt=0,k;
bool is_prime[MAX_N];
void seive()
{
	fill(is_prime,is_prime+MAX_N,true);
	for(int i=2;icnt)
	{
		puts("NOT FOUND");
	}
	else
	{
		printf("%d\n",a[k-1]);
	}
	return 0;
}


最后!谢谢阅读!ACM还是很有趣滴~!希望大家能坚持下去!收获满满的~!




你可能感兴趣的:(————ACM相关————,集训队相关)