Примеры решений задач
Задача "Вектор"
Вычислить длину вектора $\overrightarrow{a}=(x,y,z)$
Решение
Длина вектора: $|\overrightarrow{a}| = \sqrt{x^2+y^2+z^2}$
#include <stdio.h>
#include <math.h>
int main(){
// Открываем входной и выходной файл
freopen("vector.in","r",stdin);
freopen("vector.out","w",stdout);
// Ввод данных
double x, y, z;
scanf("%lf %lf %lf", &x, &y, &z);
// Вычисления и вывод ответа
printf("%.2lf\n", sqrt(x*x + y*y + z*z));
return 0;
}
Задача "Прямая по 2-м точкам"
$a{x_1}+b{y_1}+c=0$ - первая точка$a{x_2}+b{y_2}+c=0$ - вторая точка
Решить систему из 2-х линейных уравнений с 3-мя неизвестными => бесконечное количество решений (это одна прямая, и коэффициенты $a, b, c$ у всех решений пропорциональны друг другу).
$a = \frac{-b{y_1}-c}{x_1}$
$\frac{-b{y_1}-c}{x_1} {x_2}+b{y_2}+c=0$
$-b{y_1}{x_2}-c{x_2}+b{y_2}{x_1}+c{x_1}=0$
$b({y_2}{x_1}-{y_1}{x_2})+c({x_1}-{x_2})=0$
$c = 1$$b({y_2}{x_1}-{y_1}{x_2})+c({x_1}-{x_2})=0$
$b = \frac{ {x_2}-{x_1} } {{y_2}{x_1}-{y_1}{x_2}}$; $c = 1$; $a = \frac{- c - b{y_1}}{x_1}$
Умножим все уравнения на: ${{y_2}{x_1}-{y_1}{x_2}}$
$b = {x_2}-{x_1}$; $c = {{y_2}{x_1}-{y_1}{x_2}}$; $a = \frac{{- c - b{y_1}}}{x_1}{({{y_2}{x_1}-{y_1}{x_2}})}$
$a = \frac{{- ({{y_2}{x_1}-{y_1}{x_2}}) - ({x_2}-{x_1}){y_1}}}{x_1}{({{y_2}{x_1}-{y_1}{x_2}})}$
$a = \frac{{- {y_2}{x_1} + {y_1}{x_2} - {x_2}{y_1} + {x_1}{y_1}}} {x_1}{({{y_2}{x_1}-{y_1}{x_2}})}$
$a = ({y_1} - {y_2}) {({{y_2}{x_1}-{y_1}{x_2}})}$
Это частичное решение, оно работает не во всех случаях (надо отдельно разбирать когда ${y_2}{x_1}-{y_1}{x_2}=0$ ).
Другой вариант решения (для всех случаев)
$a{x_1}+b{y_1}+c=0$ - первая точка$a{x_2}+b{y_2}+c=0$ - вторая точка
Приравниваем уравнения или вычитаем из первого уравнения второе.
Получаем уравнение с двумя неизвестными: $a({x_1}-{x_2})+b({y_1}-{y_2}) = 0$
Интуиция подсказывает решение:
$a = {y_1}-{y_2}$
$b = -({x_1}-{x_2})$
$({y_1}-{y_2})({x_1}-{x_2})-({x_1}-{x_2})({y_1}-{y_2}) = 0$
#include <stdio.h>
#include <math.h>
int main(){
// Открываем входной и выходной файл
freopen("line.in","r",stdin);
freopen("line.out","w",stdout);
// Ввод данных
double x1, y1, x2, y2;
scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2);
double a = y1-y2;
double b = -(x1-x2);
double c = -(a*x1+b*y1);
// Вычисления и вывод ответа
printf("%.2lf %.2lf %.2lf\n", a, b, c);
// Проверка ответа
printf("%.2lf\n", a*x1 + b*y1 + c);
printf("%.2lf\n", a*x2 + b*y2 + c);
return 0;
}
#include <stdio.h>
#include <math.h>
const double Inf = 1.e10;
double min(double a, double b){
return (a < b) ? a : b;
}
int main(){
// Открываем входной и выходной файл
freopen("maxdist.in","r",stdin);
freopen("maxdist.out","w",stdout);
// Ввод данных
int N; // Количество вершин
scanf("%d", &N);
double X[100], Y[100];
for(int i=0; i<N; i++)
scanf("%lf %lf", &X[i], &Y[i]);
double D[100][100];
for(int i=0; i<N; i++)
for(int j=0; j<N; j++)
D[i][j] = (i==j) ? 0 : Inf;
int M; // Количество рёбер
scanf("%d", &M);
for(int i=0; i<M; i++){
int from, to;
scanf("%d %d", &from, &to);
from--; to--;
double dist = sqrt(pow(X[from]-X[to],2) + pow(Y[from]-Y[to],2));
D[from][to] = dist;
D[to][from] = dist;
}
// Сам алгоритм
for(int k=0; k<N; k++)
for(int i=0; i<N; i++)
for(int j=0; j<N; j++)
D[i][j] = min(D[i][j], D[i][k] + D[k][j]);
// Выбираем максимум
double max1 = 0.0;
for(int i=0; i<N; i++)
for(int j=0; j<N; j++){
if(D[i][j] > max1) {
max1 = D[i][j];
}
}
if((max1 > 0) && (max1 < Inf)){
printf("%0.6lf\n", max1);
} else {
printf("-1\n");
}
return 0;
}
Разбор задачи о подобных треугольниках (Пифагор)
Идея решения: перебирать стороны ища среди них пропорциональные.
#include >stdio.h<
#include >iostream<
#include >algorithm<
using namespace std;
// Задача о подобии треугольников
// Треугольники подобны, когда их стороны пропорциональны
// 1 2 3
// 2 6 4
// Стороны должны быть упорядочены по возрастанию
bool similar(int a1, int b1, int c1,
int a2, int b2, int c2 ){
return (a1*b2 == b1*a2) && (b1*c2 == c1*b2);
}
int main()
{
freopen("pifagor.in","r",stdin);
freopen("pifagor.out","w",stdout);
// Ввести исходные данные: длины сторон
int len[9], u[9];
for(int i=0; i<9; i++){
cin >> len[i];
u[i] = 0;
}
// Упорядочить (отсортировать) стороны по длине
sort(len, len + 9);
// Перебирать стороны и искать подобные треугольники
// Когда найдём, выведем на экран
for(int i=0; i<9; i++){
u[i] = 1;
for(int j=i+1; j<9; j++){
u[j] = 1;
for(int k=j+1; k<9; k++){
u[k] = 1;
for(int i2=i+1; i2<9; i2++)
if(!u[i2]){
u[i2] = 1;
for(int j2=j+1; j2<9; j2++)
if(!u[j2]){
u[j2] = 1;
for(int k2=k+1; k2<9; k2++)
if(!u[k2]){
u[k2] = 1;
if(similar(len[i],len[j],len[k],
len[i2],len[j2],len[k2])){
cout << len[i] << " " << len[j] << " " << len[k] << endl;
cout << len[i2] << " " << len[j2] << " " << len[k2] << endl;
return 0;
}
u[k2] = 0;
}
u[j2] = 0;
}
u[i2] = 0;
}
u[k] = 0;
}
u[j] = 0;
}
u[i] = 0;
}
return 0;
}