poj 2653
2016-07-21 23:28
393 查看
题目概述
在坐标系中扔N根粗细不计的木棒,每根木棒的序号为其被扔的序数,若两木棒相交,则后扔的会被视为“在顶端”,先扔的会被压在下面,给出每根木棒端点坐标,求最后有哪些木棒“在顶端”时限
3000ms/9000ms输入
每组数据第一行正整数N,其后N行,每行4个浮点数,为木棒端点坐标,输入以N=0结束限制
1<=N<=100000;1<=“在顶端”木棒数<=1000输出
每行开头为字符串Top sticks:
其后若干个数,为“在顶端”的木棒序号,两个数之间以英文逗号和空格分隔,最后输出一个英文句号
样例输入
51 1 4 2
2 3 3 1
1 -2.0 8 4
1 4 8 2
3 3 6 -2.0
3
0 0 1 1
1 0 2 1
2 0 3 1
0
样例输出
Top sticks: 2, 4, 5.Top sticks: 1, 2, 3.
讨论
计算几何,求线段相交,题充其量算模版题(早背过模版了),只是输入量巨大,想快些并不容易,看过几篇题解,通过灵活(但略复杂)运用一个数组的前几个空白位置反复记录,可以将用时降低到400-600ms,额退而求其次,开个链表,效果也说得过去,暴力的平方级方法也试过,然而3秒根本不可能够为何是“在顶端”呢?因为真正在顶端的应该是摞的最高的那个,而且只有一个,因而加了引号
题解状态
3708K,610MS,G++,1936B题解代码
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<list> using namespace std; #define INF 0x3f3f3f3f #define MAXN 100003 #define memset0(a) memset(a,0,sizeof(a)) #define EPS 1e-6 list<int>marked;//存放“在顶端”的木棒序号 list<int>::iterator it, last;//放到外面也是为了省点常数 last用于指向最后一个元素 double x[MAXN], y[MAXN], x2[MAXN], y2[MAXN];//木棒端点坐标值 inline double xp(double x1, double y1, double x2, double y2, double x3, double y3) { return (x1 - x2)*(y3 - y2) - (y1 - y2)*(x3 - x2); } inline bool onsegment(double x, double y, double x1, double y1, double x2, double y2) { return min(x1, x2) <= x&&x <= max(x1, x2) && min(y1, y2) <= y&&y <= max(y1, y2); } inline bool intersect(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) { double xp1 = xp(x3, y3, x1, y1, x2, y2); double xp2 = xp(x4, y4, x1, y1, x2, y2); double xp3 = xp(x1, y1, x3, y3, x4, y4); double xp4 = xp(x2, y2, x3, y3, x4, y4); if (xp1*xp2 < 0 && xp3*xp4 < 0) return 1; else if (abs(xp1) < EPS&&onsegment(x3, y3, x1, y1, x2, y2)) return 1; else if (abs(xp2) < EPS&&onsegment(x4, y4, x1, y1, x2, y2)) return 1; else if (abs(xp3) < EPS&&onsegment(x1, y1, x3, y3, x4, y4)) return 1; else if (abs(xp4) < EPS&&onsegment(x2, y2, x3, y3, x4, y4)) return 1; return 0; }//上面三个函数已经背的很熟练了 今天做了好几个题 也懒得解释了 void fun(int N) { for (int p = 0; p < N; p++) { scanf("%lf%lf%lf%lf", &x[p], &y[p], &x2[p], &y2[p]);//input marked.push_back(p); last = marked.end(); --last;//链表没法随机存储 只能这样 for (it = marked.begin(); it != last; ) { int a = *last, b = *it;//也是为了减小常数 if (intersect(x[a], y[a], x2[a], y2[a], x[b], y[b], x2[b], y2[b])) marked.erase(it++);//链表节点删除后迭代器也会作废 因而利用后缀++先行将下一节点算出再将旧的删除掉 else ++it;//没删还是照常递增 注意前缀++比后缀要快……一点点 } } bool f = 0;//控制逗号空格输出 printf("Top sticks: ");//output for (it = marked.begin(); it != marked.end(); ++it) { if (f) printf(", "); printf("%d", *it + 1);//output f = 1; } printf(".\n");//output } int main(void) { //freopen("vs_cin.txt", "r", stdin); //freopen("vs_cout.txt", "w", stdout); int N; while (~scanf("%d", &N) && N) {//input fun(N); marked.clear();//链表里有东西 需要清空 } }
EOF
相关文章推荐
- 2016 Multi-University Training Contest 2题解报告
- 扬帆——起航
- 阿里云ossfs同步问题
- iOS中block介绍(四)揭开神秘面纱(下)
- 蓝桥杯 ADV-205算法提高 拿糖果(动态规划)
- PHP-无限级分类(迭代法创建)
- Java正则表达式
- MFC在对话框上面绘图
- 浅谈信息的度量
- Leetcode Unique Paths II
- Android中的Parcel机制 实现Bundle传递对象
- Some thing about Graph
- POJ3666(动态规划)
- iOS中block介绍(三)揭开神秘面纱(上)
- EasyUI综合布局Layout二.银行后台局部实现模仿
- Homework--Java_File
- 各种网站和博客的收集
- class的头文件与源文件分离
- EasyUI综合布局Layout二.银行后台局部实现模仿
- EasyUI综合布局Layout二.银行后台局部实现模仿