程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> UVA 11768 - Lattice Point or Not(數論)

UVA 11768 - Lattice Point or Not(數論)

編輯:C++入門知識

UVA 11768 - Lattice Point or Not

題目鏈接

題意:給定兩個點,構成一條線段,這些點都是十分位形式的,求落在這個直線上的正數點。

思路:先把直線表達成a x + b y = c的形式,a,b, c都化為整數表示,然後利用擴展gcd求出x和y的通解,然後已知min(x1, x2) <= x <= max(x1, x2), min(y1, y2) <= y <= max(y1, y2),這樣一來就可以求出通解中t的范圍,t能取的整數就是整數解,就得到答案。

值得注意的是,直線為平行坐標系的情況,要特殊判斷一下

代碼:

#include 
#include 
#include 
#include 
using namespace std;

const long long INF = 0x3f3f3f3f3f3f3f;
int t;
long long xx1, yy1, xx2, yy2;
long long a, b, c;

long long read(){
	double t;
	scanf("%lf", &t);
	return (long long)(10 * (t + 0.05));
}

long long gcd(long long a, long long b) {
	if (!b) return a;
	return gcd(b, a % b);
}

long long exgcd(long long a, long long b, long long &x, long long &y) {
	if (!b) {x = 1; y = 0; return a;}
	long long d = exgcd(b, a % b, y, x);
	y -= a / b * x;
	return d;
}

void build() {
	a = (yy2 - yy1) * 10;
	b = (xx1 - xx2) * 10;
	c = (yy2 - yy1) * xx1 + (xx1 - xx2) * yy1;
	long long t = gcd(gcd(a, b), c);
	a /= t; b /= t; c /= t;
}

long long solve() {
	long long ans = 0;
	long long x, y;
	long long d = exgcd(a, b, x, y);
	long long up = INF, down = -INF;
	if (xx1 > xx2) swap(xx1, xx2);
	if (yy1 > yy2) swap(yy1, yy2);
	if (c % d) return ans;
	if (b / d > 0) {
		down = max(down, (long long)ceil((xx1 * d * 1.0 / 10 - x * c * 1.0) / b));
		up = min(up, (long long)floor((xx2 * d * 1.0 / 10 - x * c * 1.0) / b));
 	}
 	else if (b / d < 0) {
 		up = min(up, (long long)floor((xx1 * d * 1.0 / 10 - x * c * 1.0) / b));
		down = max(down, (long long)ceil((xx2 * d * 1.0 / 10 - x * c * 1.0) / b));
  	}
  	else if (xx1 % 10) return ans;
  	if (a / d > 0) {
  		down = max(down, (long long)ceil((y * c * 1.0 - d * yy2 * 1.0 / 10) / a));
  		up = min(up, (long long)floor((y * c * 1.0 - d * yy1 * 1.0 / 10) / a));
   	}
   	else if (a / d < 0) {
   		up = min(up, (long long)floor((y * c * 1.0 - d * yy2 * 1.0 / 10) / a));
  		down = max(down, (long long)ceil((y * c * 1.0 - d * yy1 * 1.0 / 10) / a));
   	}
   	else if (yy1 % 10) return ans;
   	if (down <= up)
   		ans += up - down + 1;
	return ans;
}

int main() {
	scanf("%d", &t);
	while (t--) {
		xx1 = read(); yy1 = read(); xx2 = read(); yy2 = read();
		build();
		printf("%lld\n", solve());
 	}
	return 0;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved