๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ“š ์ „๊ณต ๊ณต๋ถ€/๋ฌธ์ œํ•ด๊ฒฐ๊ธฐ๋ฒ•

[๋ฌธ์ œํ•ด๊ฒฐ๊ธฐ๋ฒ•] 2. ๊ธฐ์ดˆ์ˆ˜ํ•™

1. ๋ฒกํ„ฐ์˜ ์™ธ์  : cross product

 

2. ์™ธ์ ์˜ ์‘์šฉ : ๋ถ€ํ˜ธ ์ ๊ฒ€

 

3. CCW ์•Œ๊ณ ๋ฆฌ์ฆ˜ : Counter-Clock Wise

์„ธ ์ ์ด ์ฃผ์–ด์กŒ์„ ๋•Œ A->B์™€ A->C ๋‘ ๋ฒกํ„ฐ์˜ ์™ธ์ ์˜ ๋ถ€ํ˜ธ๊ฐ€ ๋ฐฉํ–ฅ์„ ๊ฒฐ์ •ํ•จ.

 

int ccw(int x1, int y1, int x2, int y2, int x3, int y3){

    int tmp = x1*y2 + x2*y3 + x3*y1;

    tmp -= (y1*x2 + y2*x3 + y3*x1);

    if(tmp > 0) return 1;    // a์— ๋Œ€ํ•ด b๊ฐ€ ๋ฐ˜์‹œ๊ณ„ ๋ฐฉํ–ฅ(์™ผ์ชฝ)์— ์žˆ์Œ

    else if(tmp < 0) return -1;    // a์— ๋Œ€ํ•ด b๊ฐ€ ์‹œ๊ณ„ ๋ฐฉํ–ฅ(์˜ค๋ฅธ์ชฝ)์— ์žˆ์Œ

    else return 0;

}

 

 

4. ์‘์šฉ : ์„ ๋ถ„์˜ ๊ต์ฐจ ์—ฌ๋ถ€

a-b๋ฅผ ์ด์€ ๋ฒกํ„ฐ A์— ๋Œ€ํ•ด a-c์™€ a-d๊ฐ€ ๋ฐ˜๋Œ€ ๋ฐฉํ–ฅ์ด๋ฉด ๋ฒกํ„ฐ A์™€ c-d๋Š” ๊ต์ฐจํ•œ๋‹ค.

 

5. ์„ ๋ถ„์˜ ๊ต์ฐจ๋ฅผ ํ‘ธ๋Š” ๋ฌด์‹ํ•œ ๋ฐฉ๋ฒ•

- ๋‘ ์„ ๋ถ„์„ ์ง์„ ์œผ๋กœ ๋ณด๊ณ  ๊ต์ ์„ ์ฐพ๊ธฐ

- ๊ต์ ์ด ๋‘ ์„ ๋ถ„ ์œ„์— ์žˆ๋Š”์ง€ ํ™•์ธ

์‹œ๊ฐ„์ด ๋งŽ์ด ์†Œ์š”, ์ •์ˆ˜๊ฐ€ ์•„๋‹Œ ์‹ค์ˆ˜ ์—ฐ์‚ฐ์œผ๋กœ ์ธํ•œ ์˜ค์ฐจ ๋ฐœ์ƒ ๊ฐ€๋Šฅ์„ฑ (๋‚˜๋ˆ—์…ˆ ํ•  ๋•Œ ๋ฌธ์ œ ๋ฐœ์ƒ)

 

6. ์™ธ์ ์„ ์ด์šฉํ•œ ์„ ๋ถ„ ๊ต์ฐจ ํŒ์ • : ๋‘ ์„ ๋ถ„ ๋ชจ๋‘์˜ ์ž…์žฅ์—์„œ ์ ๊ฒ€ํ•œ๋‹ค

 

์˜ˆ์™ธ์‚ฌํ•ญ) ๋‘ ์„ ๋ถ„์ด ๊ฒน์น˜์ง€ ์•Š์„๋•Œ(๋งŒ๋‚˜์ง€ ์•Š์„๋•Œ), ๋‘ ์„ ๋ถ„์˜ ๋์ด ๋งŒ๋‚  ๋•Œ, ๋‘ ์„ ๋ถ„์ด ๊ฒน์ณ์งˆ๋•Œ, ํ•œ ์„ ๋ถ„์ด ๋‹ค๋ฅธ์„ ๋ถ„์— ํฌํ•จ๋  ๋–„

CCW ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์œ„ 4๊ฐ€์ง€ ๊ฒฝ์šฐ์— ๋ชจ๋‘ ๊ฑฐ์ง“์ด๋‹ค.

-> ์™ธ์ ์ด 0์ด ๋œ๋‹ค๋ฉด ๊ต์ ์„ ๊ตฌํ•˜์—ฌ ์ ๊ฒ€ํ•˜๊ธฐ!!

1์ฐจ์› ์ง์„  ์ƒ์—์„œ ์„ ๋ถ„ [a, b]๋Š” ์–‘ ๋์ ์ด ์ขŒํ‘œ a, b์ธ ์ ์ด๊ณ  [c, d]๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.
์ธ์ƒ์„ ํŽธํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ a <= b, c <= d๋ผ๊ณ  ๊ฐ€์ •ํ•ฉ์‹œ๋‹ค.
left = min(a, c), right = max(b, d)
- ๋‘ ์„ ๋ถ„์ด ๋งŒ๋‚˜์ง€ ์•Š๋Š”๋‹ค :  a, b, c, d์˜ ์œ„์น˜๊ด€๊ณ„๋ฅผ ์ƒ๊ฐํ•ด๋ณด๋ฉด ์ข€ ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. 
a <= b < c <= d ๋˜๋Š” c <= d < a <= b ๋ผ๋ฉด ๋งŒ๋‚˜์ง€ ์•Š๊ฒ ์ฃ . 
์•ฝ๊ฐ„๋งŒ ์ƒ๊ฐํ•˜๋ฉด, right - left > |b-a| + |d - c| ์ž„์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‘ ์„ ๋ถ„์˜ ๊ธธ์ด์˜ ํ•ฉ์ด ๊ฐ€์žฅ ์™ผ์ชฝ ๋์ ๊ณผ ๊ฐ€์žฅ ์˜ค๋ฅธ์ชฝ ๋์ ์„ ์ž‡๋Š” ์„ ๋ถ„์˜ ๊ธธ์ด๋ณด๋‹ค ์งง์€ ๊ฒƒ์ด์ฃ .
๋น„์Šทํ•˜๊ฒŒ, 
- ๋‘ ์„ ๋ถ„์ด ํ•œ ์ ์—์„œ ๋งŒ๋‚œ๋‹ค : 
a <= b = c <= d ๋˜๋Š” c <= d = a <= b์ด์ง€๋งŒ 
right - left = |b - a| + |d - c|
- ๋‘ ์„ ๋ถ„์ด ๊ต์ฐจํ•œ๋‹ค : 
right - left < |b - a| + |d - c| 
- ํ•œ ์„ ๋ถ„์ด ๋‘ ์„ ๋ถ„ ์•ˆ์— ์™„์ „ํžˆ ํฌํ•จ๋œ๋‹ค:
rifht - left = |b - a| or |d - c|

 

 

7. ๋‘ ์ˆ˜์˜ ์ตœ๋Œ€ ๊ณต์•ฝ์ˆ˜ ์ฐพ๊ธฐ : ์œ ํด๋ฆฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ (Euclid)

 

GCD(a,b) = GCD(b, a-b)

why? a=a'g, b=b'g -> b-a = (b' - a')g

 

O( log max(a,b) ) -> ์†Œ์ธ์ˆ˜๋ถ„ํ•ด๋ณด๋‹ค ๋น ๋ฆ„.

์ตœ์•…์˜ ์ƒํ™ฉ : ํ”ผ๋ณด๋‚˜์น˜ ์ˆซ์ž

ax+by = GCD(a,b)

 

unsigned int gcd(unsigned int a, unsigned int b){
	if(a<b) return gcd(b,a);
    if(b==0) return a;
    return gcd(b, a - b); // ๋บ„์…ˆ
}

// ๋” ๋น ๋ฅธ gcd
unsigned int gcd(unsigned int a, unsigned int b){
	if(a<b) return gcd(b,a);
    if(b==0) return a;
    return gcd(b, a % b); // ๋‚˜๋จธ์ง€ ์—ฐ์‚ฐ
}

 

~ ์ธ๋ณต ๋ง์”€ ~

GCD(23, 5) = GCD(5, 3)
3 = 23*1 - 5*4
GCD(5, 3) = GCD(3, 2)
2 = 5 - 3 = 5 - (23*1 - 5*4) = 5*5 - 23*1
GCD(3, 2) = GCD(2, 1) = GCD(1, 0) 
1 = 3 - 2 = (23*1 - 5*4) - (5*5 - 23*1) 
= 23*2 - 5*9 

์ •๋ฆฌ 1. GCD(a, b)๋ฅผ ์œ ํด๋ฆฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ๊ตฌํ•˜๋Š” ๊ณผ์ •์—์„œ GCD๋ฅผ ๊ตฌํ•˜๋Š” ๋‘ ์ˆ˜๋Š” ํ•ญ์ƒ ax+by๊ผด์ด๋‹ค. 
(= ๊ฒฐ๊ตญ ์ด ์ค‘ ํ•˜๋‚˜๊ฐ€ GCD(a, b)์ด๊ธฐ ๋•Œ๋ฌธ์— GCD(a, b) = ax+by๊ฐ€ ๋˜๋Š” x, y๊ฐ€ ์กด์žฌํ•œ๋‹ค)

์ฆ๋ช…. ์ˆ˜ํ•™์  ๊ท€๋‚ฉ๋ฒ•. 
๊ธฐ๋ณธ) a = a*1 + b*0, b = a*0 + b*1
๊ท€๋‚ฉ) GCD(ax + by, a'x + b'y)๋ฅผ ๊ตฌํ•  ๋•Œ ax + by > a'x + b'y๋ผ๊ณ  ๊ฐ€์ •ํ•˜๋ฉด 
GCD(ax + by, a'x + b'y) = GCD(a'x + b'y, ((ax+by) - (a'x+b'y))
= GCD(a'x + b'y, (a-a')x + (b-b')y) ์ด๋ฏ€๋กœ ํ•ญ์ƒ ์„ฑ๋ฆฝํ•œ๋‹ค.  

 

8. ์œ ํ•œ์ฒด : Finite Field

์ž์—ฐ์ˆ˜๋ฅผ ์†Œ์ˆ˜ p๋กœ ๋‚˜๋ˆˆ ๋‚˜๋จธ์ง€์˜ ์ง‘ํ•ฉ Z = {0,1,...,p-1}

์ด ์ง‘ํ•ฉ์—์„œ ๋ง์…ˆ, ๋บ„์…ˆ, ๊ณฑ์…ˆ์„ ์ •์˜ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

 

๋‚˜๋ˆ—์…ˆ์€? -> ๊ณฑ์…ˆ์ด ์„ฑ๋ฆฝํ•œ๋‹ค๋Š” ์กฐ๊ฑด์„ ํ™œ์šฉ

๊ณฑ์…ˆ์— ๋Œ€ํ•œ ํ•ญ๋“ฑ์›์€ 1์ด๋ฏ€๋กœ, ๋‚˜๋ˆ—์…ˆ์€ ๊ณฑํ•ด์„œ 1์ด ๋˜๋Š” ์ˆ˜๋ฅผ ์ฐพ๋Š” ๊ณผ์ •์ด๋‹ค (๊ณฑ์…ˆ์˜ ์—ญ์›)

 

a * x = 1 (mod p)

 

9. ์œ„ ์‹์—์„œ x๋ฅผ ๊ตฌํ•˜๋Š” ๊ฒƒ์ด ํ™•์žฅ ์œ ํด๋ฆฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค

 

์„œ๋กœ์†Œ์ธ p์™€ a๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ, ab = 1 (mod p) ์˜ b๋ฅผ ๊ตฌํ•˜์‹œ์˜ค.

-> GCD(a,p) = ax + py ์ธ x, y๊ฐ€ ์กด์žฌํ•˜๋ฉฐ, ์ด ๊ฐ’์€ a์™€ p๊ฐ€ ์„œ๋กœ์†Œ์ด๋ฏ€๋กœ 1์ด๋‹ค.

๋”ฐ๋ผ์„œ GCD(a,p) = 1์„ ๊ตฌํ•˜๋Š” ๊ณผ์ •์—์„œ ์ด ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” x๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

a=4, p=7์ด๋ผ๊ณ  ํ•˜๋ฉด

GCD(4,7) = GCD(4, 7-4) = GCD(7-4, 4-(7-4)) = GCD(4-(7-4), (7-4)%(4-(7-4))) = 1

์ด ์‹ ์ค‘์—์„œ 4-(7-4) = 4 + 4 - 7 = 4*2 - 7*1 = 1 ์ด๋ฏ€๋กœ, b = 2

 

10. Extended Euclidean Algorithm

 

#include <iostream>
using namespace std;

int xGCD(int a, int b, int &x, int &y){
    if(b==0) {
        cout << x << " " << y << "\n";
        return a;
    }
    cout << x << " " << y << "\n";
    int x1, y1;
    x1 = y;
    y1 = x - (a / b) * y;
    int gcd = xGCD(b, a % b, x1, y1);
    return gcd;
}

int main(){
    int x = 1;
    int y = 0;
    cout << xGCD(4, 7, x, y);
    
}

 

๋งˆ์ง€๋ง‰์— ์ถœ๋ ฅ๋œ x = 2

 

์—ฌ๊ธฐ์„œ 

x1 = y;

y1 = x - (a / b) * y;

์ด ์‹์ด ๋‚˜์˜จ ์ด์œ ๋Š”, gcd(a, b) = gcd(b, a%b) ์—์„œ 

bx + (a%b)y = bx + (a - (a/b)*b)y = ay + b(x - (a/b)y) ์ด๋ ‡๊ฒŒ ์ •๋ฆฌ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๊ทธ๋ž˜์„œ ์ƒˆ๋กœ์šด x1์— y๊ฐ€ ๋“ค์–ด๊ฐ€๊ณ , ์ƒˆ๋กœ์šด y1์— x - (a/b) * y ๊ฐ€ ๋Œ€์ž…๋˜๋Š” ๊ฒƒ์ด๋‹ค.