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