2015百度之星初赛(1)题解(1001)

1001:  简单的贪心题。首先我们特判必赢和必输的两种状态(max<m,min>m),然后对战斗力排序,找到在0~m之间最大的战斗力作为初始值,

然后,每一次将攻击力提升至 下一个彪形大汉的值,同时k--,如果一旦发现打不过,那么必输,break。注意战斗力1e12,用__int64

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
__int64 s[10005];
int main()
{
	__int64 T, n, m, k;
	scanf("%I64D", &T);
	__int64 cas = 1;
	while (T--)
	{
		scanf("%I64D%I64D%I64D", &n,&m,&k);
		for (__int64 i = 1; i <= n; i++)
			scanf("%I64D", &s[i]);
		sort(s + 1, s + n + 1);
		cout << "Case #" << cas++ << ":" << endl;
		if (s[n] <= m)
		printf("why am I so diao?\n");
		else if (s[1] > m)
		printf("madan!\n");
		else
		{
			__int64 ind = 0;
			for (__int64 i = 1; i <= n; i++)
			{
				if (s[i] >= 0 && s[i] <= m)
					ind = i;
			}
			__int64 attack = s[ind];
		   int flag = 1;
		   for (__int64 i = ind; i <= n; i++)
			{
				if (attack < s[i])
				{
					flag = 0;
					break;
				}
				else if (attack == s[i])
				{
					if (i + 1 <= n&&attack + k >= s[i + 1])
					{
						attack = attack + s[i + 1] - s[i];
						k--;
						k = max(k, (__int64)0);
					}
				}

			}
			if (flag)
				printf("why am I so diao?\n");
			else
				printf("madan!\n");
		}
	}
	return 0;
}

1006 :

最小矩形覆盖,模板题。注意结果是四舍五入。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
#define PR 1e-8
#define N 4010
#define maxdouble 1e20
int T, n, ans;
struct TPoint
{
    double x, y;
};
struct TPolygon
{
    int n;
    TPoint p[N];
}ply;
double MIN(double a, double b) { return a>b ? b : a; }
int dblcmp(double a)
{
    if (fabs(a)<PR) return 0;
    return a>0 ? 1 : -1;
}
double dist(TPoint a, TPoint b)//距离
{
    double s1 = a.x - b.x;
    double t1 = a.y - b.y;
    return sqrt(s1*s1 + t1*t1);
}
double cross(TPoint a, TPoint b, TPoint c)//叉积
{
    double s1 = b.x - a.x;
    double t1 = b.y - a.y;
    double s2 = c.x - a.x;
    double t2 = c.y - a.y;
    return s1*t2 - s2*t1;
}
double dot(TPoint a, TPoint b, TPoint c)//点积
{
    double s1 = b.x - a.x;
    double t1 = b.y - a.y;
    double s2 = c.x - a.x;
    double t2 = c.y - a.y;
    return s1*s2 + t1*t2;
}
bool cmop(TPoint a, TPoint b)//x、y排序
{
    if (fabs(a.x - b.x)<PR) return a.y<b.y;
    else return a.x<b.x;
}
bool cmp(TPoint a, TPoint b)//叉积内排序
{
    int d1 = dblcmp(cross(ply.p[0], a, b));
    return d1>0 || (d1 == 0 && dist(ply.p[0], a)<dist(ply.p[0], b));
}
TPolygon graham()//求凸包
{
    int i, top = 2;
    for (i = 2; i<ply.n; i++)
    {
        while (top>1 && (dblcmp(cross(ply.p[top - 2], ply.p[i], ply.p[top - 1]))) >= 0) top--;
        ply.p[top++] = ply.p[i];
    }
    ply.n = top;
    return ply;
}
double solve()
{
    int i, p = 1, q = 1, r;
    double minarea = maxdouble, area;
    ply.p[ply.n] = ply.p[0];
    for (i = 0; i<ply.n; i++)
    {
        while (dblcmp(cross(ply.p[i], ply.p[i + 1], ply.p[p + 1])//最上一点
            - cross(ply.p[i], ply.p[i + 1], ply.p[p]))>0)
            p = (p + 1) % ply.n;
        while (dblcmp(dot(ply.p[i], ply.p[i + 1], ply.p[q + 1])//最右一点
            - dot(ply.p[i], ply.p[i + 1], ply.p[q]))>0)
            q = (q + 1) % ply.n;
        if (i == 0) r = q;
        while (dblcmp(dot(ply.p[i], ply.p[i + 1], ply.p[r + 1])//最左一点
            - dot(ply.p[i], ply.p[i + 1], ply.p[r])) <= 0)
            r = (r + 1) % ply.n;
        double d = dist(ply.p[i], ply.p[i + 1])*dist(ply.p[i], ply.p[i + 1]);
        area = cross(ply.p[i], ply.p[i + 1], ply.p[p])*
            (dot(ply.p[i], ply.p[i + 1], ply.p[q]) - dot(ply.p[i], ply.p[i + 1], ply.p[r])) / d;
        minarea = MIN(area, minarea);//更新
    }
    return minarea;
}
int main()
{
    scanf("%d", &T);
    //while (scanf("%d", &ply.n), ply.n)
    for (int Case = 1; Case <= T; ++Case)
    {
        scanf("%d", &n);
        ply.n = 4 * n;
        int i;
        double area;
        for (i = 0; i<ply.n; i++) scanf("%lf%lf", &ply.p[i].x, &ply.p[i].y);
        sort(ply.p, ply.p + ply.n, cmop);//排序
        sort(ply.p + 1, ply.p + ply.n, cmp);
        ply = graham();//凸包
        if (ply.n<3) area = 0;
        else area = solve();
        printf("Case #%d:\n", Case);
        ans = area + 0.5;
        printf("%d\n", ans);
    }
    return 0;
}
时间: 2024-11-08 11:59:02

2015百度之星初赛(1)题解(1001)的相关文章

二分查找 2015百度之星初赛1 1001 超级赛亚ACMer

题目传送门 1 /* 2 二分找到不大于m的最大的数,记做p,只要a[p] + k <= a[p+1]就继续 3 注意:特判一下当没有比m小的数的情况:) 4 */ 5 #include <cstdio> 6 #include <cstring> 7 #include <cmath> 8 #include <algorithm> 9 using namespace std; 10 11 typedef long long ll; 12 13 const

数学 2015百度之星初赛2 HDOJ 5255 魔法因子

题目传送门 1 /* 2 数学:不会写,学习一下这种解题方式:) 3 思路:设符合条件的数的最高位是h,最低位是l,中间不变的部分为mid,由题意可得到下面的公式(这里对X乘上1e6用a表示,b表示1e6) 4 (h*power+l+mid)*a = (l*power+h+mid)*b 5 可推得:mid = ((h*power+l) * a - (l*power+h) * b) / (a - b); 6 所以可以枚举h,l然后求mid,注意mid的最低位一定是0,因为留出最低位加l或者h 7

LIS 2015百度之星初赛2 HDOJ 5256 序列变换

题目传送门 1 /* 2 LIS(非严格):首先我想到了LIS,然而总觉得有点不对:每个数先减去它的下标,防止下面的情况发生:(转载) 3 加入序列是1,2,2,2,3,这样求上升子序列是3,也就是要修改2个,但是中间的两个2,变化范围又不能超过(1,3) 4 那么这样求的也就不对,但是减掉之后,相当于给中间重复的数留下了修改的空间 5 解释下为什么可以减而保持正确性:因为题目所求时严格递增,假设是2,3, 4,那么变成1, 1, 1,所以在LIS里非严格递增就可以了 6 这也是为什么要在upp

二分搜索 2015百度之星初赛1 1003 序列变换

题目传送门 1 /* 2 二分搜索:在0-1e6的范围找到最小的max (ai - bi),也就是使得p + 1 <= a[i] + c or a[i] - c 3 比赛时以为是贪心,榨干智商也想不出来:( 4 */ 5 #include <cstdio> 6 #include <algorithm> 7 #include <cstring> 8 #include <cmath> 9 #include <iostream> 10 using

BFS 2015百度之星初赛2 HDOJ 5254 棋盘占领

题目传送门 1 /* 2 BFS:先把1的入队,每个1和它相邻的组合后看看能不能使0变1,若有则添加入队,change函数返回改变了多少个0 3 注意:结果还要加上原来占领的 4 */ 5 #include <cstdio> 6 #include <algorithm> 7 #include <cstring> 8 #include <cmath> 9 #include <vector> 10 #include <queue> 11

Kruskal 2015百度之星初赛2 HDOJ 5253 连接的管道

题目传送门 1 /* 2 最小生成树(Kruskal):以权值为头,带入两个端点,自然的排序;感觉结构体的并查集很好看 3 注意:题目老头要的是两个农田的高度差,中文水平不好,题意理解成和平均值的高度差! 4 */ 5 #include <cstdio> 6 #include <algorithm> 7 #include <cstring> 8 #include <cmath> 9 #include <vector> 10 #include &l

2015 百度之星 初赛1 1001(贪心)

 Problem Description 百小度是一个ACMer,也是一个超级赛亚人,每个ACMer都有一个战斗力,包括百小度.?所谓超级赛亚人的定义,是说如果在对抗中刚好接近极限状态,那就会激发斗志,实力提升.? 具体来说,就是百小度现在要接受一些ACMer的挑战了,这些ACMer有n个人,第i个人的战斗力是a[i]. ?百小度接下来可以自主安排与这n个ACMer的PK顺序,他要想在PK赛中赢过另外一个ACMer,就必须使得自己的战斗力不小于对方(平局情况他会按照百小度字典上的规则把自己排

百度之星初赛签到(1001/1005)

A:Polynomial Polynomial Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description 度度熊最近学习了多项式和极限的概念. 现在他有两个多项式 f(x)f(x) 和 g(x)g(x),他想知道当 xx 趋近无限大的时候,f(x) / g(x)f(x)/g(x) 收敛于多少. Input 第一行一个整数 T~(1 \leq T \leq

2015百度之星初赛2 1005 序列变换(LIS变形)

LIS(非严格):首先我想到了LIS,然而总觉得有点不对:每个数先减去它的下标,防止下面的情况发生:(转载) 3 加入序列是1,2,2,2,3,这样求上升子序列是3,也就是要修改2个,但是中间的两个2,变化范围又不能超过(1,3) 4 那么这样求的也就不对,但是减掉之后,相当于给中间重复的数留下了修改的空间 5 解释下为什么可以减而保持正确性:因为题目所求时严格递增,假设是2,3, 4,那么变成1, 1, 1,所以在LIS里非严格递增就可以了 6 这也是为什么要在upper_bound的位置插入