EOJ 3724. 求和公式(非暴力)

本文介绍了一种高效计算矩形区域内特定直线上的整点个数的方法,避免了暴力法的时间复杂度过高问题。通过判断直线与矩形的交点,并计算横纵坐标投影长度,实现了快速求解。特别注意当n为奇数时,中心点可能被重复计算的情况。

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

这个题今天终于解决了,谢谢eoj上shwei大佬的代码呀!

本题链接如下:

https://acm.ecnu.edu.cn/problem/3724/

 

判断y=x与y=n-1-x两条直线在矩形区域内的整点个数:

思路一:暴力法 x1<=x<=x2计算每个点的y1,y2值判断在不在矩形区域内(时间复杂度大,在eoj上过不了)

思路二:判断矩形区域与直线的交点,每条直线1的个数就是交点的横坐标投影长度(x2-x1+1)或纵坐标的投影长度(y2-y1+1)。这样就转化成求矩形区域和两条直线的交点并求出投影。求交点关键是如何判断直线与矩形是否相交,考虑清楚直线和矩形的位置情况,x1,y1,x2,y2满足什么条件才和矩形区域相交。

注意:若n为奇数时,中心点可能会被重复计算,所以要判断是否包含中心点,若包含需在最终答案中减1。

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll n,x1,y1,x2,y2,sum;
int q;
int main()
{
	cin>>n>>q;
	for(int i=0;i<q;i++)
	{
		sum=0;
		cin>>x1>>y1>>x2>>y2;
		x1++,y1++,x2++,y2++;
		//统计对角线
		if(x1<=y1){
			//矩形在直线上方时 
			if(x1!=y1){
				//若相交分为两种情况:(底边,左侧边),(底边,上侧边) 
				if(x2-y1>=0) 
					//综合两种情况取最小值 
					sum+=min(x2,y2)-y1+1; 				
			}  
			//肯定相交分为两种情况:(底边,左侧边),(底边,上侧边)
			if(x1==y1){
				//综合两种情况取最小值 
				sum+=min(x2,y2)-y1+1;	
			}
		}
		//矩形在直线下方时 
		else{
			//先判断是否和直线相交
			//若相交:两种情况:(右边,上边),(右边,左侧边) 
			if(y2-x1>=0){
				sum+=min(x2,y2)-x1+1;
			} 
		}
		//统计 反对角线 
		//将考虑的矩形对称
		//依据考虑与y=x交点 
		ll tmp = y1;
        y1 = n + 1 - y2;
        y2 = n + 1 - tmp; 
        if(x1<=y1){
			//矩形在直线上方时 
			if(x1!=y1){
				//若相交分为两种情况:(底边,左侧边),(底边,上侧边) 
				if(x2-y1>=0) 
					//综合两种情况取最小值 
					sum+=min(x2,y2)-y1+1; 				
			}  
			//肯定相交分为两种情况:(底边,左侧边),(底边,上侧边)
			if(x1==y1){
				//综合两种情况取最小值 
				sum+=min(x2,y2)-y1+1;	
			}
		}
		//矩形在直线下方时 
		else{
			//先判断是否和直线相交
			//若相交:两种情况:(右边,上边),(右边,左侧边) 
			if(y2-x1>=0){
				sum+=min(x2,y2)-x1+1;
			} 
		}
		
		// 处理中心点是否被重复计算
        ll mid = n / 2 + 1;
        //若为奇数并且在矩形区域内 
        if (n & 1 == 1 && (mid >= x1 && mid <= x2 && mid >= n + 1 - y2 && mid <= n + 1 - y1)) sum--;

        cout << sum << endl;
	}
	return 0;	
} 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值