【扩展欧几里德】SGU 106

KIDx的解题报告

 

题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=106

 

题意:求ax + by + c = 0在[x1, x2], [y1, y2]区间内有多少组解?

 

解析:

令c = -c有ax + by = c,可用扩展欧几里德解方程解出特解

当然要先考虑a = 0, b = 0, c = 0的情况进行特判

例如:a = 0, b = 1, c = 3,x∈[x1, x2], y∈[3, 4]

即可得知有方程有x2-x1+1个解,因为x可以区间内任意,且y=3这个解在区间内,其他情况同理了

②然后就是关键了,用的是扩展欧几里德通解式:(设一整数k,x0为x的特解)

1、x1 <= x0+k*b <= x2

2、y0 = (c - a*x0) / b

3、y1 <= y0+k'*b <= y2

解出k和k'的范围[s, e]!

注意了,例如解x1 <= x0+k*b:

当b<0时两边同时除以b,<=要变成>=号

--->k <= (x1-x0) / b

然后最关键就是除不尽应该向什么方向舍入?

区间[s, e]的舍入方向:

正数s, e的情况:

可见s = (x1-x0)/b还要+1,e直接除即可
负数s, e的情况:

可见e = (x1-x0)/b还要-1,s直接除即可

③最后得到x的k的范围[s1, e1], y的k'的范围[s2, e2]

因为x增加必然导致y减小,所以有:

举个例子,如图所示:令-e2作为s2,令-s2作为e2,答案为[-e2, e1]
 

所以答案ans = min (e1, e2') - max (s1, s2') + 1;

#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <map>
#include <algorithm>
#include <math.h>
using namespace std;
#define M 1005
#define LL long long

LL gcd (LL a, LL b)
{
	return b ? gcd (b, a%b) : a;
}

void Egcd (LL a, LL b, LL &x, LL &y)
{
	if (b == 0)
	{
		x = 1, y = 0;
		return ;
	}
	LL tp;
	Egcd (b, a%b, x, y);
	tp = x;
	x = y;
	y = tp - a/b*y;
}

LL cal (LL f, LL n, int key)			//处理舍入问题
{
	if (f % n == 0) return f/n;
	if (key == 0)
	{
		if (f * n < 0) return f/n;
		return f/n+1;
	}
	if (f * n < 0) return f/n-1;
	return f/n;
}

LL a, b, c;
LL solve (LL &x1, LL &x2, LL &y1, LL &y2)
{
	LL d, x, y, s1, e1, s2, e2;
	c = -c;
	/***********************特判***********************/
	if (a == 0 && b == 0 && c == 0)
		return (x2-x1+1) * (y2-y1+1);
	if (a == 0 && b == 0) return 0;
	if (a == 0)
	{
		if (c % b != 0) return 0;
		y = c / b;
		if (y >= y1 && y <= y2) return x2 - x1 + 1;
		return 0;
	}
	if (b == 0)
	{
		if (c % a != 0) return 0;
		x = c / a;
		if (x >= x1 && x <= x2) return y2 - y1 + 1;
		return 0;
	}
	/***********************特判***********************/
	d = gcd (a, b);
	if (c % d != 0) return 0;
	a /= d, b /= d, c /= d;
	Egcd (a, b, x, y);

	x *= c;
	x = (x % b + b) % b;						 //x的特解
	s1 = cal (x1-x, b, b<0);						//s1
	e1 = cal (x2-x, b, b>0);						//e1

	y = (c - a*x) / b;							 //有了x,求对应的y
	e2 = -cal (y1-y, a, a<0);					//e2' = -s2
	s2 = -cal (y2-y, a, a>0);					//s2' = -e2

	if (b < 0) s1 ^= e1, e1 ^= s1, s1 ^= e1;		//b为负数,变号导致区间头尾互换
	if (a < 0) s2 ^= e2, e2 ^= s2, s2 ^= e2;		//同理

	LL ans = min (e1, e2) - max (s1, s2)  + 1;
	if (ans < 0) ans = 0;

	return ans;
}

int main()
{
	LL x1, x2, y1, y2;
	while (~scanf ("%lld%lld%lld", &a, &b, &c))
	{
		scanf ("%lld%lld%lld%lld", &x1, &x2, &y1, &y2);
		printf ("%lld\n", solve (x1, x2, y1, y2));
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码下载:完整代码,可直接运行 ;运行版本:2022a或2019b或2014a;若运行有问题,可私信博主; **仿真咨询 1 各类智能优化算法改进及应用** 生产调度、经济调度、装配线调度、充电优化、车间调度、发车优化、水库调度、三维装箱、物流选址、货位优化、公交排班优化、充电桩布局优化、车间布局优化、集装箱船配载优化、水泵组合优化、医疗资源分配优化、设施布局优化、可视域基站和无人机选址优化 **2 机器学习和深度学习方面** 卷积神经网络(CNN)、LSTM、支持向量机(SVM)、最小二乘支持向量机(LSSVM)、极限学习机(ELM)、核极限学习机(KELM)、BP、RBF、宽度学习、DBN、RF、RBF、DELM、XGBOOST、TCN实现风电预测、光伏预测、电池寿命预测、辐射源识别、交通流预测、负荷预测、股价预测、PM2.5浓度预测、电池健康状态预测、水体光学参数反演、NLOS信号识别、地铁停车精准预测、变压器故障诊断 **3 图像处理方面** 图像识别、图像分割、图像检测、图像隐藏、图像配准、图像拼接、图像融合、图像增强、图像压缩感知 **4 路径规划方面** 旅行商问题(TSP)、车辆路径问题(VRP、MVRP、CVRP、VRPTW等)、无人机三维路径规划、无人机协同、无人机编队、机器人路径规划、栅格地图路径规划、多式联运运输问题、车辆协同无人机路径规划、天线线性阵列分布优化、车间布局优化 **5 无人机应用方面** 无人机路径规划、无人机控制、无人机编队、无人机协同、无人机任务分配 **6 无线传感器定位及布局方面** 传感器部署优化、通信协议优化、路由优化、目标定位优化、Dv-Hop定位优化、Leach协议优化、WSN覆盖优化、组播优化、RSSI定位优化 **7 信号处理方面** 信号识别、信号加密、信号去噪、信号增强、雷达信号处理、信号水印嵌入提取、肌电信号、脑电信号、信号配时优化 **8 电力系统方面** 微电网优化、无功优化、配电网重构、储能配置 **9 元胞自动机方面** 交通流 人群疏散 病毒扩散 晶体生长 **10 雷达方面** 卡尔曼滤波跟踪、航迹关联、航迹融合

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值