POJ2653 Pick-up sticks

PS: 去年省赛前做过一遍,这次基本就不用模版做第二次,比较基础。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
const double eps = 1e-10;
int n;

int dcmp(double x) {
    if(fabs(x)<eps) return 0;
    else return x > 0 ? 1 : -1;
}
struct point {
    double x, y;
    point(double x=0, double y=0):x(x),y(y){}
};
struct stick {
    point a, b;
};
vector<stick> v;
point operator - (point A, point B) {
    return point(A.x-B.x, A.y-B.y);
}

double Cross(point A, point B) {
    return A.x*B.y - A.y*B.x;
}
double Dot(point A, point B) {
    return A.x*B.x + A.y*B.y;
}
bool SegInter(point a1, point a2, point b1, point b2) {
    double c1 = Cross(a2-a1, b1-a1), c2 = Cross(a2-a1, b2-a1);
    double c3 = Cross(b2-b1, a1-b1), c4 = Cross(b2-b1, a2-b1);
    return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}

bool OnSegment(point p, point a1, point a2) {
    return dcmp(Cross(a1-p, a2-p))==0 && dcmp(Dot(p-a1, p-a2))<=0;
}
vector<int> res;
int main()
{
    point t1, t2;
    stick tmp;
    while(scanf("%d", &n)!= EOF && n) {
        v.clear();
        v.push_back(tmp);
        for(int i =1; i <= n; i++) {
            scanf("%lf%lf%lf%lf", &tmp.a.x, &tmp.a.y, &tmp.b.x, &tmp.b.y);
            v.push_back(tmp);
        }
        int i, j;
        bool first, second, third;
        res.clear();
        for( i = 1; i <= n; i++) {
            for( j = i+1; j <= n; j++) {
                first = SegInter(v[i].a, v[i].b, v[j].a, v[j].b);
                second = OnSegment(v[i].a, v[j].a, v[j].b);
                third = OnSegment(v[i].b, v[j].a, v[j].b);
                if(first || second || third) break;
            }
            if(j>n) res.push_back(i);
        }
        printf("Top sticks: ");
        if(res.size()==1) {
            printf("%d.\n", res[0]);
            continue;
        } else {
            int len = res.size();
            for(int i = 0; i < len-1; i++) {
                printf("%d, ", res[i]);
            }
            printf("%d.\n", res[len-1]);
        }
    }
    return 0;
}

POJ2653 Pick-up sticks,码迷,mamicode.com

时间: 2024-11-08 22:47:24

POJ2653 Pick-up sticks的相关文章

2015南阳CCPC D - Pick The Sticks 背包DP.

D - Pick The Sticks Description The story happened long long ago. One day, Cao Cao made a special order called "Chicken Rib" to his army. No one got his point and all became very panic. However, Cao Cao himself felt very proud of his interesting

2015南阳CCPC D - Pick The Sticks dp

D - Pick The Sticks Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 无 Description The story happened long long ago. One day, Cao Cao made a special order called "Chicken Rib" to his army. No one got his point and all became very panic. However, Cao

hdu5543(Pick The Sticks) 01背包

Pick The Sticks Time Limit: 15000/10000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 2540    Accepted Submission(s): 850 Problem Description The story happened long long ago. One day, Cao Cao made a special order

HDU 5543 Pick The Sticks:01背包变种

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5543 题意: 给你N个金条和一张长度为L的桌子.每个金条长度为a[i],价值为w[i].金条只能在桌子上横着摆一排,并且只要金条的重心(中心)在桌子上,就可以放.问你在桌子上能够摆的金条的最大总价值. 题解: 首先表示状态: 考虑到第i个金条,在这之前已经占用了j的长度,在k个端点摆了金条.即:dp[i][j][k] 如何转移(逆推): 对于第i个金条,有三种决策:摆在桌子中央.摆在桌子端点处.不摆

HDU 5543 Pick The Sticks

背包变形.与普通的背包问题不同的是:允许有两个物品可以花费减半. 因此加一维即可,dp[i][j][k]表示前i个物品,有j个花费减半了,总花费为k的情况下的最优解. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include&l

题解:UESTC1218 Pick The Sticks

题意:选择长度为ai,价值为vi金条覆盖长度为L的区域,使总价值最大,只要金条重心在区域内即可. 1<=N<=1000;1<=L<=2000;1<=ai<=2000;1<=vi<=109. 共1~100组数据,10000MS 注意:0/1背包的简单变形:显然最多有2次机会让金条在长度变为一半的情况下价值不变,为了避免0.5的出现,将长度,价值都乘上2,DP[i][j][k]表示选择到第i个金条,占用长度为j且已经用了k次机会时最大价值,复杂度O(3*NL).

HDU 5543 Pick The Sticks (01背包)

题意:输入t,表示t组样例, 输入n,len,表示物品的个数和容器长度.输入n行a,v表示没个物品的长度和价值.每个物品只要能有一半放在容器上就可以(为了平衡,如果是一个物品的话不论它有多长都可以放在这个容器上),不可以重叠,求这个容器可以放最大的价值是多少. 分析:dp[i][j][k]表示前i个物品中放入长度为j的容器中有k个物品在边缘的最大价值. #include <iostream> #include <cstdio> #include <cstring> #i

DP(01背包) UESTC 1218 Pick The Sticks (15CCPC C)

题目传送门 题意:长度为L的金条,将n根金棍尽可能放上去,要求重心在L上,使得价值最大,最多有两条可以长度折半的放上去. 分析:首先长度可能为奇数,先*2.然后除了两条特殊的金棍就是01背包,所以dp[now][j][k]表示当前状态,长度为j,使用了k条特殊金棍获得的最大价值,需要对内存和时间优化. /************************************************ * Author :Running_Time * Created Time :2015/10/2

hdu 5543 Pick The Sticks(动态规划)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5543 题意:给你一根长为m的长木板和一些小木棒,每一根小木棒有它的长度和价值,这些小木棒要放在长木板上并且每一根小木棒的重心要在长木板上(即可以露出一半的长),问最大价值是多少. dp[i][j][k]  表示前i个小棒放到长度为j的木板上,其中有k个小棒放在边沿部分(边沿部分的小棒需要尽量放在木板外面,所以放在边沿的木棒落在木板上的长度为l/2).然后就是简单的01背包问题了. #include

ACM学习历程—UESTC 1218 Pick The Sticks(动态规划)(2015CCPC D)

题目链接:http://acm.uestc.edu.cn/#/problem/show/1218 题目大意就是求n根木棒能不能放进一个容器里,乍一看像01背包,但是容器的两端可以溢出容器,只要两端的木棒的重心还在容器中即可. 首先由于木棒可以两端溢出.一端溢出和不溢出三种情况,所以有状态p(flag, v)表示溢出个数为flag的容量为v的情况下的最值. 于是有: p[2][j] = max(p[2][j], p[2][j-a[i]]+v[i]); p[2][j] = max(p[2][j],