zoukankan      html  css  js  c++  java
  • 【题解】AcWing 1390.通电围栏

    题目传送门

    题目描述

    农夫约翰的牧场可以看作是一个二维平面。

    约翰为了方便看管他养的牛,构建了一个三角形的通电围栏。

    他希望他的奶牛都在围栏围起的区域内活动。

    三角形围栏的三个顶点位置坐标分别为 (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 的时候是要求的两条线之间的点,就要相减了

    还有两点注意点

    1. 当这个点算出刚好是整点的情况
    2. 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;
    }
    
  • 相关阅读:
    [USACO12FEB]牛券Cow Coupons
    合并果子
    序列合并
    中位数
    道路游戏
    教主的花园
    摆花
    hello world之Makefile
    mysql+tomcat+spring 配置心得(从0开始搭环境)
    C#,.Net自动生成大写字母编码
  • 原文地址:https://www.cnblogs.com/RemnantDreammm/p/15127675.html
Copyright © 2011-2022 走看看