您的位置:首页 > 大数据 > 人工智能

2014 Multi-University Training Contest 10 部分题目解题报告

2014-08-22 20:36 561 查看
Source:

http://acm.hdu.edu.cn/search.php?field=problem&key=2014%20Multi-University%20Training%20Contest%2010&source=1&searchmode=source

这场挺坑的,题面很糟糕,admin也不给力= =。。听说这套题是去年BJTU出的,出题人已经退役,所以admin不明来源(所以很逗。。)

HDOJ 4971 A simple brute force problem.

题意:n个任务,m个技术难题,每个任务有获利,每个难题有解决的费用,有的任务需要解决一些难题才能做,难题之间会有依赖关系(实际的依赖关系和题面是反的)。选一些任务,求最大获利。

分析:20个任务,可以直接枚举,但是case有100组。这题数据比较水,所以实际上枚举+剪枝就可以过。正解自然是网络流。这一块还掌握的不行,这题大概是一个最小割和权闭合图的模型,源点连边到任务,边权为获利,难题连边到汇点,边权为费用,每个任务连权无穷的边到需要解决的问题,同时依赖的问题也要连上(任务1需要难题1,难题1依赖于难题2,那么任务1需要连边到难题1和2),跑一遍最大流,总获利减去最大流就是答案。待补。

HDOJ 4972 A simple dynamic programming problem

题意:两队打篮球赛,每次进球后只记录分差,问最终比分可能的情况数。(题面又坑爹了=。=)

分析:题面坑爹导致思路各种跑偏。由于我们知道最后的分差,所以可以只考虑两队总得分的种数。思考后发现我们不确定的情况只有两种,分差从1到2以及从2到1,总分可能+1或+3,遇上这种情况可能的总分就多一种,记2到1和1到2的总数为cnt,最后如果分差为0答案就是cnt+1,否则是2cnt+2(A队高分或A队低分)。然后还要注意各种不合法情况,就是相邻分差大于3,以及分差不变(除了1)。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<set>
#include<map>
#include<queue>
#include<ctime>
#include<string>
using namespace std;

const double pi = acos(-1.0);
int n;
double d;
const double eps = 1e-8;
inline int sign(double a){
return a < -eps ? -1 : a > eps;
}
#define cross(p1, p2, p3) ((p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y))
#define crossOp(p1, p2, p3) sign(cross(p1, p2, p3))
struct point{
double x, y, id;
point(){}
point(double _x, double _y): x(_x), y(_y){}
bool operator < (const point &p) const{
int c = sign(x - p.x);
if (c) return c == -1;
return sign(y - p.y) == -1;
}
point operator -(const point &p) const{
return point(x - p.x, y - p.y);
}
double dot(const point &p) const{
return x * p.x + y * p.y;
}
};

double dis(point a, point b)
{
return sqrt((a.x - b.x)*(a.x - b.x) + (a.y -b.y)*(a.y-b.y));
}
int onSegment(point p, point q1, point q2)
{
return crossOp(q1, q2, p) == 0 && sign((p-q1).dot(p-q2)) <= 0;
}
vector<point> convexHull(vector<point> ps)
{
int n = ps.size();
if (n <= 1)
return ps;
sort(ps.begin(), ps.end());
vector<point> qs;
for (int i = 0; i < n; qs.push_back(ps[i++])){
while(qs.size() > 1 && crossOp(qs[qs.size()-2], qs.back(), ps[i]) <= 0)
qs.pop_back();
}
for (int i = n - 2, t = qs.size(); i >= 0; qs.push_back(ps[i--])){
while((int)qs.size() > t && crossOp(qs[(int)qs.size()-2], qs.back(), ps[i]) <= 0)
qs.pop_back();
}
qs.pop_back();
return qs;
}

vector<point> p, ans;
int T;
int main()
{
scanf("%d", &T);
int cas = 0;
while(T--)
{
p.clear();
scanf("%d %lf", &n, &d);
double x, y;
for (int i = 0; i < n; i++){
scanf("%lf %lf", &x ,&y);
p.push_back(point(x, y));
}
ans = convexHull(p);
double C = 0;
int size = ans.size();
for (int i = 0; i < size; i++){
C += dis(ans[i], ans[(i+1)%size]);
}
printf("Case #%d: %.4lf\n", ++cas, C/pi/d);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: