2017 Multi-University Training Contest
来源:互联网 发布:旅游数据分析报告 编辑:程序博客网 时间:2024/05/21 11:17
其他题目题解:
2017 Multi-University Training Contest - Team 7:1005. Euler theorem
2017 Multi-University Training Contest - Team 7:1011. Kolakoski
2017 Multi-University Training Contest - Team 7:1003. Color the chessboard
2017 Multi-University Training Contest - Team 7:1002. Build a tree
2017 Multi-University Training Contest - Team 7:1010. Just do it
一开始很少人做这道,估计都被1010卡住了,实际是道水题
题意:坐标系中有n个点,每个点都有它的价值,除此之外任意两点之间都有连线,连线的价值是两个点的价值乘积,现在你可以画一条经过原点的直线,你可以获得这条直线穿过的所有线段的价值和,求最大价值
题解:所有点按斜率排序,注意不是无脑从小到大,因为斜率的变化范围是(0,∞) (-∞,0),所以要稍微处理一下
之后考虑一条与x轴重合的直线,所有在一二象限的点和在x轴正半轴上的点都在直线上面,其他都在直线下面
记录valup为所有上方点的价值和,valdown为所有下方点的价值和,
这样可以O(n)计算这条直线获得的价值(∑val[i]*valdown (i∈up))
然后就可以慢慢的顺时针旋转这条直线,直到翻转180°,中间每经过一个点就说明当前点跑到了直线的另外一边,重新计算一次价值和,最后中间的最大价值就是答案
但这复杂度不是O(n²)的么,遍历O(n),每次计算O(n)
其实不然,因为每次只有一个点发生变化,所以可以O(1)重新计算答案
假设遍历到x点时,x从直线的上端到了直线下端
那么显然有sum -= val[i]*valdown;valdown += val[i];valup -= val[i];sum += valup
这样就只有排序的复杂度了
#include<stdio.h>#include<algorithm>using namespace std;#define LL long longtypedef struct Point{double x, y;double k;LL t, val;bool operator < (const Point &b) const{if(k>0 && b.k<0)return 1;else if(k<0 && b.k>0)return 0;elsereturn k<b.k;}}Point;Point s[50005];int main(void){LL T, n, i, up, down, now, ans;scanf("%lld", &T);while(T--){scanf("%lld", &n);up = down = 0;for(i=1;i<=n;i++){scanf("%lf%lf%lld", &s[i].x, &s[i].y, &s[i].val);if(s[i].y>=0){if(s[i].x==0)s[i].k = 1e9+1000;elses[i].k = s[i].y/s[i].x;if(s[i].y==0 && s[i].x<0){down += s[i].val;s[i].t = -1;}else{up += s[i].val;s[i].t = 1;}}else{if(s[i].x==0)s[i].k = 1e9+1000;elses[i].k = s[i].y/s[i].x;down += s[i].val;s[i].t = -1;}}now = 0;for(i=1;i<=n;i++){if(s[i].t==1)now += s[i].val*down;}ans = now;sort(s+1, s+n+1);for(i=1;i<=n;i++){if(s[i].t==1){s[i].t = -1;now -= s[i].val*down;up -= s[i].val;down += s[i].val;now += s[i].val*up;}else{s[i].t = 1;now -= s[i].val*up;up += s[i].val;down -= s[i].val;now += s[i].val*down;}ans = max(ans, now);}printf("%lld\n", ans);}return 0;}
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- #2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- #2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- HDU-2188-悼念512汶川大地震遇难同胞——选拔志愿者 【巴什博弈】
- 二维最小乘积生成树
- 定时打印
- JAVA输入一串数字,转换成汉字显示
- mysql索引总结----mysql 索引类型以及创建
- 2017 Multi-University Training Contest
- 函数防抖和节流
- Class.forName()用法详解
- 通过百度API,搜索地名,实现地图和经纬度的查询
- C++之写了placement new也要写placement delete(52)---《Effective C++》
- Dependency Diagram(Junit5依赖关系图)
- 机器学习总结(一):线性回归、岭回归、Lasso回归
- Android 数据库(1)----- SQLite Litepal GreenDao 介绍
- 桥接模式