Comet OJ-2019国庆欢乐赛

国庆玩的有点嗨,开学了补题。

A轰炸平面镇魂曲

题目描述

虹村万泰是一位二维世界的替身使者,他的替身 "轰炸平面镇魂曲" 能产生一条直线分割整个平面。

一开始,平面上有一个矩形,其左下顶点坐标为 (a,b)(a,b),右上顶点坐标为 (c,d)(c,d),此矩形已把平面分成两个区域 (矩形内和矩形外)。

现在,虹村万泰对这个平面使用了两次 "轰炸平面",产生的直线分别是 x=0x=0 与 y=0y=0。

万泰想知道现在整个平面一共被分成了几个区域,你能帮帮他吗? (面积严格大于 00 才算是一个区域。)

输入描述

输入第一行包含一个整数 TT,表示输入的询问数量。

接下来 TT 行,每行四个整数,依次表示该组询问的 a,b,c,d意义如题面所示。

  • 1≤T≤10000

  • −109≤a,b,c,d≤109, a < ca<c,b < db<d

输出描述

依序对于每个询问都输出一行包含一个整数,表示该询问的区域的个数。

样例输入 1 

3
1 2 3 4
-5 5 10 20
1 0 3 4

样例输出 1

5
6
5

样例解释 1

第一组样例的示意图Image

第二组样例的示意图2.png

其中红线为x=0x=0的直线,绿线为y=0y=0的直线,蓝色的线为初始平面上的矩形。

解题思路:简单推理已知题意所示两条直线(其实就是数学中平面直角坐标系的x轴y轴)已经将所有区域划分为四个区域。

而题目中又要求a<c,b<d;所以不难想到每次询问中的矩形面积都严格大于0,然后就可以想象一下,一共是有三种情况的,①:

矩形与两条直线都不相交,则有(a*c>=0&&b*d>=0)也即是说所有坐标点都是同号的,②:矩形交于两条直线,此时根据矩形的特征结合直角坐标系来判断,不难知道(a,b)点在坐标系左下角,(c,d)点在坐标系右上角,a*c与b*d两两异号。③:矩形只与一条直线相交且保证不是底边或顶边与直线重合(重合的情况为a*c==0或b*d==0归于第一类情况了),这里的情况比较多,一个个想可能比较复杂,但这是最后一种情况了,可以取个巧,有兴趣的可以自己推理一下。注意一下数据范围。代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define inf 1e9
#define rep(i,j,k) for(int i = (j); i <= (k); i++)
#define rep__(i,j,k) for(int i = (j); i < (k); i++)
#define per(i,j,k) for(int i = (j); i >= (k); i--)
#define per__(i,j,k) for(int i = (j); i > (k); i--)
const int N=1e5+10;
int t;
LL a,b,c,d;
int main()
{
	scanf("%d",&t);
	rep(i,1,t){
		scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
		if(a*c>=0&&b*d>=0)printf("5\n");
		else if(a*c<0&&b*d<0)printf("8\n");
		else printf("6\n");
	}
    return 0;
}

B 卖萌鸡尾酒

题目描述

众所周知,鸡尾酒的群名片叫作 "卖萌鸡尾酒",他认为一个群里的 「有缘人」是群名片与他相近的人。 现在,鸡尾酒想找出群里的 「有缘人」。

首先,他将自己名片拆分成五个字 ""、""、""、""、"",并分别作为关键字进行搜索,每次搜索都会找到所有群名片包含这个字的群友。如:搜索 "" 就能找到所有名片中包含 "" 的人。

如果某个人在至少两次搜索中都被搜索到,则鸡尾酒认为他是一位 「有缘人」。如 "[jwju]鸡尾酒的小迷弟" 以及 "尾酒" 是「有缘人」。 而 "王萌♂萌" 则不是。 现在告诉你鸡尾酒的五次搜索中每一次搜索到的人数,他想知道,群里最多有几位 「有缘人」。

输入描述

输入一行包含五个正整数 a,b,c,d,e分别代表五次搜索中被搜索到的人数。

1≤a,b,c,d,e≤109

输出描述

输出一行一个整数代表群里最多有几位「有缘人」。

样例输入 1 

1 1 1 1 1

样例输出 1

2

样例解释 1

如果第一个「有缘人」包含前两个关键字,第二个「有缘人」包含后三个关键字,群里没有其他人的名片包含关键字。则每次搜索都只会有一个人被搜到,满足题意。且没有一种方案可以使得群里具有更多数量的「有缘人」且同时符合样例输入,所以群里最多有两位「有缘人」。

解题思路:这道题仔细想想还是挺有趣的。给定五次查询结果,让判断最多有多少位有缘人。咋一看是没有思路的,可以从查询结果着手,不管怎样,五次查询肯定会有一次查询人数是最多的,而当最多的这次查询比其他四次查询人数总和还多的情况下,最理想的结果莫过于另外四组查询中每个人都是有缘人;反之,则可以用所有查询的总人数除以2作为有缘人的最大结果(即使查询结果两两结合,又判断了不存在某组查询的人数比其他的总和还多,所以是成立的),注意数据范围。代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define inf 1e9
#define rep(i,j,k) for(int i = (j); i <= (k); i++)
#define rep__(i,j,k) for(int i = (j); i < (k); i++)
#define per(i,j,k) for(int i = (j); i >= (k); i--)
#define per__(i,j,k) for(int i = (j); i > (k); i--)
const int N=1e5+10;
LL a[5],sum;
int main()
{
	rep(i,0,5){
		scanf("%lld",&a[i]);
		sum+=a[i];
	}
	sort(a,a+5);
	if(a[4]>sum-a[4])cout<<sum-a[4]<<endl;
	else cout<<sum/2<<endl;
    return 0;
}

 

posted @ 2019-10-08 20:37  whocarethat  阅读(125)  评论(0编辑  收藏  举报