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;
}



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值