UVA 1393 Highways

本文详细解释了如何解决UVA1393Highways问题,即计算给定矩阵中所能连出的非水平和非竖直的直线的个数。通过枚举矩形大小并利用最大公约数判断重复情况,实现高效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UVA 1393 Highways

题意:给你一个n*m的点阵,让你求出矩阵中所能连出的非水平和非竖直的直线的个数。

思路:

  方向‘/’ 和 方向 ‘\’ 对称,枚举直线所在矩形的i*j,直线可能重复的情况:

    1、与矩形内部矩形的直线重复

    2、与它左上角的直线连接成一条

  如果gcd(i,j)>1, 那么这条直线与gcd(i,j)=1的直线是重复的,所以只枚举互质的i,j 。以左上角坐标为(0,0),这个矩形的左上角为(x,y),它合法的条件是 x+i<a,y+j<b,一共有(a-i)*(b-j)个。这个矩形左上方的矩形的左上角为(x-i,y-j),它合法的条件是 x-i>=0,x+i<a,y-j>=0,y+j<b,一共有(a-2*i)*(b-2*j)种放法。所以大小为i*j的矩形一共有 (a-i)*(b-j)-max(0,a-2*i)*max(0,b-2*j) 种放法

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,g[301][301]; 
int gcd(int x,int y){
    return x==0?y:gcd(y%x,x);
}
int main(){
    for(int i=1;i<=300;i++)    
        for(int j=1;j<=300;j++)
            g[i][j]=gcd(i,j);
    while(scanf("%d%d",&n,&m)&&n!=0&&m!=0){
        long long ans=0;
        for(int i=1;i<n;i++)
            for(int j=1;j<m;j++)
                if(g[i][j]==1)
                    ans+=(n-i)*(m-j)-max(0,n-2*i)*max(0,m-2*j);
        cout<<ans*2<<endl;
    }
}

 

转载于:https://www.cnblogs.com/cangT-Tlan/p/7607748.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值