LuoGu P2735 电网 Electric Fences

本文分享了一种解决特定数学问题的方法,通过引入皮克定理来计算网格中三角形的面积,避免了传统方法中可能遇到的精度问题。文章详细介绍了如何应用皮克定理,并提供了代码实现。

题目传送门

这个东西,本来我是用求出两条一次函数解析式然后判断在x坐标下的y坐标值来做的

首先因为没考虑钝角三角形,WA了

然后又因为精度处理不好又WA了

一气之下,只能去网上查了查那个皮克定理

首先用皮克定理需要知道:在(0,0)到(n,m)这条线段上的整点个数有gcd(n,m)+1个,至于怎么证明,我没有深究(会用不就完了

这是对于一条过原点的线段,不过原点的线段呢?我是这样理解的:我把坐标系的原点平移到了该线段的的某个端点上,以这个点的坐标为原点,把上面的式子写出来,然后......就解决了

皮克定理:在网格点中三角形的面积: 2S = 2a + b - 2(我太懒了,复制一个吧

其中,s表示三角形面积,a表示图形内点数,b为图形边界上的点数

然后利用推导公式(不就是逆用嘛):a=(2s-b+2)/2就行了。

但是嘞,又是该死的精度!

这样会造成一定的精度丢失,那怎么办?

尽量减少除法就行了!

把公式改为a=s-b/2+1,这样精度的问题就可以忽略了,然后就A掉了呢

#include <algorithm> 
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#define max(a,b) (a>b?a:b)
#define k1 (double(m)/double(n))
#define k2 (double(m)/double(n-p))
#define b (-p*k2)

using namespace std;

double n,m,p;
double tot;

int main(){
 scanf("%lf%lf%lf",&n,&m,&p);
 tot=double(__gcd((int)n,(int)m)+__gcd((int)fabs(p-n),(int)m)+p);
 printf("%.0lf\n",p*m/2-tot/2+1);
 return 0;
}

转载于:https://www.cnblogs.com/Equinox-Flower/p/9600573.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值