hdu 6127---Hard challenge(思维)
生活随笔
收集整理的這篇文章主要介紹了
hdu 6127---Hard challenge(思维)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接
?
Problem Description There are?n?points on the plane, and the?ith points has a value?vali, and its coordinate is?(xi,yi). It is guaranteed that no two points have the same coordinate, and no two points makes the line which passes them also passes the origin point. For every two points, there is a segment connecting them, and the segment has a value which equals the product of the values of the two points. Now HazelFan want to draw a line throgh the origin point but not through any given points, and he define the score is the sum of the values of all segments that the line crosses. Please tell him the maximum score.?
Input The first line contains a positive integer?T(1≤T≤5), denoting the number of test cases.For each test case:
The first line contains a positive integer?n(1≤n≤5×104).
The next?n?lines, the?ith line contains three integers?xi,yi,vali(|xi|,|yi|≤109,1≤vali≤104).
?
Output For each test case:A single line contains a nonnegative integer, denoting the answer.
?
Sample Input 2 2 1 1 1 1 -1 1 3 1 1 1 1 -1 10 -1 0 100?
Sample Output 1 1100 題意:有 n 個點,每個點有個權值,點與點之間可以連成線段,線段的權值就是兩個端點的權值乘積。任意兩個點與原點不可能在一條直線上,求一條直線穿過的線段的最大權值和? 思路:我們可以想到,有一條過原點的直線,那么直線穿過的線段都是由直線兩側的點互相連線組成的線段,進一步發現線段的權值和就是兩側的點權值和的乘積。有了前面的簡化,我們可以對所有的點按照斜率進行排序,從最小斜率的點開始遍歷計算,每次以過當前點的原點的直線為直線,那么我們需要計算兩側點權值和的乘積,那么復雜度是O(n*n)。我們可以優化:第一次以O(n) 遍歷計算直線兩側的權值和,那么緊接著的下一次的直線劃分的上下兩側只有上次的那個點不同,所以只需要O(1)的考慮上次直線上的那么點是應該加入上側還是下側。 所以這部分的做法是O(n) 的,但因為斜率排序是O(n*logn)的,所以整體的復雜度是 O(n*logn)的。 代碼如下: #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cmath> using namespace std; typedef long long LL; const LL N=5e4+5; const double INF=1e18; struct Node{LL x,y;LL v;double f; }a[N];void cal(Node& t) {LL x=t.x;LL y=t.y;if(x==0) t.f=INF;else{t.f=(double)y*1.0/(double)x;} } LL cmp(const Node s1,const Node s2) {return s1.f<s2.f; } bool check(Node a,Node b) {if(((a.x*b.y-a.y*b.x)*1.0/a.x)>=0.0)return true;return false; }int main() {LL T; cin>>T;while(T--){LL n; scanf("%lld",&n);LL tot=0;for(LL i=1;i<=n;i++){scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].v);tot+=a[i].v;cal(a[i]);}if(n==1) { puts("0"); continue; }sort(a+1,a+n+1,cmp);LL ans=0,tmp1=0,tmp2=0;tmp1=a[1].v;for(LL i=2;i<=n;i++){if(!check(a[1],a[i]))tmp1+=a[i].v;}tmp2=tot-tmp1;ans=max(tmp1*tmp2,ans);if(a[1].x<0) tmp1-=a[1].v;for(LL i=2;i<=n;i++){if(a[i].x>=0) tmp1+=a[i].v;tmp2=tot-tmp1;ans=max(tmp1*tmp2,ans);if(a[i].x<0) tmp1-=a[i].v;}printf("%lld\n",ans);}return 0; }?
轉載于:https://www.cnblogs.com/chen9510/p/7367878.html
總結
以上是生活随笔為你收集整理的hdu 6127---Hard challenge(思维)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 全面介绍Windows内存管理机制及C+
- 下一篇: YUV格式分析详解