题目描述
农夫约翰的牧场可以看作是一个二维平面。
约翰为了方便看管他养的牛,构建了一个三角形的通电围栏。
他希望他的奶牛都在围栏围起的区域内活动。
三角形围栏的三个顶点位置坐标分别为 (0,0),(n,m),(p,0),该围栏由三个顶点两两相连而成。
平面上,所有位于三角形围栏内部(不包括边)且横纵坐标都为整数的点上都可以放置一头奶牛。
请问,围栏中最多可以放置多少头奶牛。
输入格式
共一行,包含三个整数 n,m,p。
输出格式
输出一个整数,表示可放置的牛的最大数量。
数据范围
0≤n<32000,
0<m<32000,
0<p<32000
输入样例:
7 5 10
输出样例:
20
算法1
(暴力?模拟) \(O(n)\)
就是把每个x的三角形三条线所对的y值算出,然后想想自己怎么做的,就是统计y1到y2点有几个,
这边也没有特别的暴力,比较完全暴力是\(O(n^2)\)时间会超,所以运用简单的数学知识中的斜率来做就好。
这里需要注意的主要是n与p的关系
n < p 的时候下面的线是k = 0 的线
n > p 的时候是要求的两条线之间的点,就要相减了
还有两点注意点
- 当这个点算出刚好是整点的情况
- double的精度误差
C++ 代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
int n, m, p;
double k1, k2, b2;
inline int get_cnt(double x)
{
if(p > n)
{
if(x < n) return (int)(k1 * x - 1e-8);
return (int)(k2 * x + b2 - 1e-8);
}
if(x < p) return (int)(k1 * x - 1e-8);
return (int)(k1 * x - 1e-8) - (int)(k2 * x + b2 + 1e-8); // l2: (- 1e-8) x
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m >> p;
k1 = 1.0 * m / n, k2 = 1.0 * m / (n - p), b2 = - k2 * p;
// cout << k1 << ' ' << k2 << ' ' << b2 << endl;
LL res = 0;
for(int i = 1; i < max(p, n); i ++)
{
res += get_cnt(i);
// cout << get_cnt(i) << endl;
}
cout << res << endl;
return 0;
}