Zoj 3647 Gao the Grid (数论?)

这是一道关于寻找最少三角形的题目,涉及大数处理和数学技巧。原问题由于n较大不适合暴力解决,尝试过斜率枚举和平移的方法未果。AC代码采用从直线端点出发,利用数论中的__gcd(i, j) - 1计算不合法组合,结合平移策略得出答案。" 111487244,10296414,C语言实现三角形类型判断,"['C语言', '算法', '数学', '程序设计']
摘要由CSDN通过智能技术生成

给你n * m 的的矩形方格, 也即有(n + 1) * (m + 1) 个点, 然后问可以找到做少个三角形。

n比较大显然是不能暴力枚举的, 然后想dp递推也发现太复杂了,,于是想逆向求解,比赛的时候想的是枚举斜率, 然后判断当前斜率下右多少点共线, 再考虑平移, 可是还是不对,,跟ac代码比了很多样例都是没问题的。。醉了。

然后Ac代码的解题方式是, 枚举每条直线的一个端点, 另一个端点是0,0,然后这条直线上,选两个端点的情况下, 不符合条件的方法数就是__gcd(i, j) - 1。然后再考虑平移然后再乘二,再用总的方法数减掉就可以了。

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cctype>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <sstream>
#include <iostream>
#include <algorithm>
using namespace std;
#define ls id<<1,l,mid
#define rs id<<1|1,mid+1,r
#define OFF(x) memset(x,-1,sizeof x)
#define CLR(x) memset(x,0,sizeof x)
#define MEM(x) memset(x,0x3f,sizeof x)
typedef long long ull ;
typedef pair<int,int> pii ;
const int maxn = 1e5+50 ;
const int inf = 0x3f3f3f3f ;
const int MOD = 1e9+7 ;

ull a[1055];
void init() {
    a[2] = 0;
    for (int i = 3; i <= 1005; i++) a[i] = a[i - 1] + i * (i - 1) * (i - 2) / 6;
//    cout << a[1000] << "\n" ;
}

int main () {
#ifdef LOCAL
	freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
//      freopen("C:\\Users\\Administrator\\Desktop\\out.txt","w",stdout);
#endif
    int n,m;init();
    while (~scanf("%d%d", &n, &m)) {
        ull tmp = 0;
        for (int i = 2; i <= n; i++) {
            for (int j = 2; j <= m; j++) {
                tmp += 1LL * (__gcd(i,j) - 1) * (n - i + 1) * (m - j + 1) * 2;
            }
        }
        tmp += 1LL * (m + 1) * (n + 1) * (n - 1) * n / 6;
        tmp += 1LL * (n + 1) * (m + 1) * (m - 1) * m / 6;
        ull d = (m + 1) * (n + 1);
        ull ans = d * (d - 1) * (d - 2) / 6;
        cout << ans - tmp << "\n" ;
    }

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值