SPOJ AMR10A Playground(计算几何)

Playground

Time limit:2s
Source limit:50000B
Memory limit:256MB



My kid's school cleared a large field on their property recently to convert it into a playing area.  The field is polygonal.  The school administration decided to separate the field into two areas by building a straight picket fence between the area for the older kids and the area for the younger kids.  The fence would go between two non-adjacent vertices of the polygonal field, and given the shape of the field, all such possible fences would lie strictly and entirely within the field. 
Naturally, the smaller of the two areas would go to the younger kids.  So can you help the school determine what the area of the smaller play-area would be for different fence positions? 
 
INPUT
The first line contains 2 numbers N denoting the number of points in the convex polygon and Q denoting the number of possible locations of straight line fences. 
The next N lines contain 2 integers each. The ith line contains the integers xi yi denoting the coordinates of the ith point of the polygon. The points are given in clockwise order. 
The next Q lines contain 2 integers a b denoting that a straight line fence is to be drawn connecting a and b. 
 
OUTPUT
Output Q lines one corresponding to each query. For each query, output the area of the smaller region for the corresponding query truncated to 1 decimal place. Always have 1 digit after the decimal place, so if the answer is 1, output it as 1.0 instead. 
 
CONSTRAINTS 
4 <= N <= 50000 
1 <= Q <= 50000 
-20,000,000 <= x,y <= 20,000,000 
0 <= a < b-1 
b < N 
 
SAMPLE INPUT
4 2 
0 0 
0 1 
1 2 
1 0 
1 3 
0 2 
 
SAMPLE OUTPUT
0.5 
0.5 
 
EXPLANATION
The polygon is given by the points (0,0) (0,1) (1,2) (1,0).  
In the first query, we join the points (0,1) and (1,0) which leads to the 2 areas given by (0,0) (0,1) (1,0) and (0,1) (1,2) (1,0). The first triangle has an area of 0.5 and the second triangle has an area of 1. The minimum of these 2 is 0.5. 
In the second query, we join the points (0,0) and (1,2) which leads to the 2 areas given by (0,0) (0,1) (1,2) and (0,0) (1,2) (1,0). The first triangle has an area of 0.5 and the second triangle has an area of 1. The minimum of these 2 is 0.5.


题意:顺时针给出构成多边形的n个点的坐标,然后进行Q次询问,每次给出两个点,意思是在这两个点之间连一条线,把多边形分成2部分,求这两部分中面积较小的那部分的面积是多少。


分析:如果每次连线之后都重新求面积,会做很多重复的工作,最终导致超时。正确解法是:利用三角形的有向面积求出多边形面积的同时,再求出面积的前缀和,当在两个点之间连一条线时,只需用前缀和相减即可。


#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
struct node
{
    double x, y;
}a[50005];
double sum[50005];
double area2(double x0, double y0, double x1, double y1, double x2, double y2)
{
    return x0 * y1 + x2 * y0 + x1 * y2 - x2 * y1 - x0 * y2 - x1 * y0;
}
int main()
{
    int n, Q, i, j;
    while(~scanf("%d%d",&n,&Q))
    {
        for(i = 0; i < n; i++)
        {
            scanf("%lf%lf",&a[i].x, &a[i].y);
        }
        double Area = 0;
        sum[0] = 0;
        for(i = 1; i <= n - 2; i++)
        {
            Area += area2(a[0].x, a[0].y, a[i].x, a[i].y, a[i+1].x, a[i+1].y);
            sum[i] = Area;
        }
        double total_area = fabs(Area / 2);
        int u, v;
        double tmp_area;
        while(Q--)
        {
            scanf("%d%d",&u, &v);
            if(u > v) swap(u, v);
            if(u == 0)
                tmp_area = fabs(sum[v-1]/2);
            else if(v == n-1)
                tmp_area = total_area - fabs(sum[u-1] + area2(a[0].x, a[0].y, a[u].x, a[u].y, a[v].x, a[v].y))/2;
            else
                tmp_area = fabs(sum[v-1] - sum[u-1] - area2(a[0].x, a[0].y, a[u].x, a[u].y, a[v].x, a[v].y))/2;
            printf("%.1lf\n", min(tmp_area, total_area - tmp_area));
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
洛谷的SPOJ需要注册一个SPOJ账号并进行绑定才能进行交题。您可以按照以下步骤进行注册: 1. 打开洛谷网站(https://www.luogu.com.cn/)并登录您的洛谷账号。 2. 在网站顶部导航栏中找到“题库”选项,将鼠标悬停在上面,然后选择“SPOJ”。 3. 在SPOJ页面上,您会看到一个提示,要求您注册SPOJ账号并进行绑定。点击提示中的链接,将会跳转到SPOJ注册页面。 4. 在SPOJ注册页面上,按照要求填写您的用户名、密码和邮箱等信息,并完成注册。 5. 注册完成后,返回洛谷网站,再次进入SPOJ页面。您会看到一个输入框,要求您输入刚刚注册的SPOJ用户名。输入用户名后,点击“绑定”按钮即可完成绑定。 现在您已经成功注册并绑定了SPOJ账号,可以开始在洛谷的SPOJ题库上刷题了。祝您顺利完成编程练习!\[1\]\[2\] #### 引用[.reference_title] - *1* *3* [(洛谷入门系列,适合洛谷新用户)洛谷功能全解](https://blog.csdn.net/rrc12345/article/details/122500057)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [luogu p7492 序列](https://blog.csdn.net/zhu_yin233/article/details/122051384)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值