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