zoukankan      html  css  js  c++  java
  • 【组合&取补集】数三角形 @CQOI2014/BZOJ3505/upcexam3843

    http://exam.upc.edu.cn/problem.php?id=3843&csrf=8oK86t2oHSgi3Q4SX3qOJGeENe6pfXri
    时间限制: 1 Sec 内存限制: 128 MB
    题目描述
    给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个。下图为4x4的网格上的一个三角形。
    注意:三角形的三点不能共线。n×m的网格共有(n+1)×(m+1)个格点。
    输入
    输入一行,包含两个空格分隔的正整数m和n(1<=m,n<=1000)。
    输出
    输出一个正整数,为所求三角形数量。
    样例输入
    2 2
    样例输出
    76

    取补集的思想,三角形的数量等于任取三点的情况减去三点共线的情况

    #define FILE() freopen("../../in.txt","r",stdin)
    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    
    ll combine(int n) { //n个点取3个
        ll m=n,res=1;
        for(int i=0; i<3; i++) {
            if(m%3==0) {
                res*=m/3;
            } else res*=m;
            m--;
        }
        return res/2;
    }
    
    int gcd(int a,int b){
        return b?gcd(b,a%b):a;
    }
    
    int main() {
    //    FILE();
        int n,m;
        cin>>n>>m;
        ll ans = combine((n+1)*(m+1))-(n+1)*combine(m+1)-(m+1)*combine(n+1); //先减去横竖格线上三点共线的
        for(int i=1; i<=n; i++) {
            for(int j=1; j<=m; j++) { //类似向量,从(0,0)到(i,j)作一线段 gcd(i,j)+1为线段上格点的数量
                ans-=(gcd(i,j)-1)*(n-i+1)*(m-j+1)*2; //乘2是因为沿y轴翻转情况一样
            }
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    Java ClassLoader机制
    Spring JMS
    MySQL权限分配
    Java参数传递机制
    JVM装载过程
    PowerDesigner15使用时的十五个问题
    修改当前行 传值
    WebSphere MQ
    Hibernate Search牛刀小试 (转)
    关于hibernate的缓存使用
  • 原文地址:https://www.cnblogs.com/NeilThang/p/9356628.html
Copyright © 2011-2022 走看看