Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Алгоритмы.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
340.64 Кб
Скачать

16) Диофантовы уравнения

int gcd (int a, int b, int & x, int & y) {

if (a == 0) {

x = 0; y = 1;

return b;

}

int x1, y1;

int d = gcd (b%a, a, x1, y1);

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

y = x1;

return d;

}

 

bool find_any_solution (int a, int b, int c, int & x0, int & y0, int & g) {

g = gcd (abs(a), abs(b), x0, y0);

if (c % g != 0)

return false;

x0 *= c / g;

y0 *= c / g;

if (a < 0) x0 *= -1;

if (b < 0) y0 *= -1;

return true;

}

A,b>0;

17) Нахождение степени делителя факториала

Даны два числа:   и  . Требуется посчитать, с какой степенью делитель   входит в число  , т.е. найти наибольшее   такое, что   делится на  .

int fact_pow (int n, int k) {

int res = 0;

while (n) {

n /= k;

res += n;

}

return res;

}

18) Дискретное логарифмирование

Задача дискретного логарифмирования заключается в том, чтобы по данным целым  ,  ,   решить уравнение:

где   и   — взаимно просты

int solve (int a, int b, int m) {

int n = (int) sqrt (m + .0) + 1;

 

int an = 1;

for (int i=0; i<n; ++i)

an = (an * a) % m;

 

map<int,int> vals;

for (int i=1, cur=an; i<=n; ++i) {

if (!vals.count(cur))

vals[cur] = i;

cur = (cur * an) % m;

}

 

for (int i=0, cur=b; i<=n; ++i) {

if (vals.count(cur)) {

int ans = vals[cur] * n - i;

if (ans < m)

return ans;

}

cur = (cur * a) % m;

}

return -1;

}

19) Нахождение площади простого многоугольника

double sq (const vector<point> & fig)

{

double res = 0;

for (unsigned i=0; i<fig.size(); i++)

{

point

p1 = i ? fig[i-1] : fig.back(),

p2 = fig[i];

res += (p1.x - p2.x) * (p1.y + p2.y);

}

return fabs (res) / 2;

}

20) Теорема Пика.

Многоугольник без самопересечений называется решётчатым, если все его вершины находятся в точках с целочисленными координатами (в декартовой системе координат)

Пусть дан некоторый решётчатый многоугольник, с ненулевой площадью.

Обозначим его площадь через  ; количество точек с целочисленными координатами, лежащих строго внутри многоугольника — через  ; количество точек с целочисленными координатами, лежащих на сторонах многоугольника — через  .

Тогда справедливо соотношение, называемое формулой Пика:

21) Пересечение окружности и прямой

Дана окружность (координатами своего центра и радиусом) и прямая (своим уравнением). Требуется найти точки их пересечения (одна, две, либо ни одной).

Сначала найдём ближайшую к центру точку прямой - точку с некоторыми координатами (x0,y0). Во-первых, эта точка должна находиться на таком расстоянии от начала координат:

|C|

----------

sqrt(A2+B2)

_________________________

A C

x0 = - -----

A2+B2

B C

y0 = - -----

A2+B2

_____________________________________

C2

d = sqrt ( r2 - ----- )

A2+B2

_____________________________________

d2

mult = sqrt ( ----- )

A2+B2

ax = x0 + B mult

ay = y0 - A mult

bx = x0 - B mult

by = y0 + A mult

double r, a, b, c; // входные данные

double x0 = -a*c/(a*a+b*b), y0 = -b*c/(a*a+b*b);

if (c*c > r*r*(a*a+b*b)+EPS)

puts ("no points");

else if (abs (c*c - r*r*(a*a+b*b)) < EPS) {

puts ("1 point");

cout << x0 << ' ' << y0 << '\n';

}

else {

double d = r*r - c*c/(a*a+b*b);

double mult = sqrt (d / (a*a+b*b));

double ax,ay,bx,by;

ax = x0 + b * mult;

bx = x0 - b * mult;

ay = y0 - a * mult;

by = y0 + a * mult;

puts ("2 points");

cout << ax << ' ' << ay << '\n' << bx << ' ' << by << '\n';

}