Перейти к содержимому


Публикации Санек

37 публикаций создано Санек (учитываются публикации только с 14-мая 23)



#52 Точка в круге

Отправлено от Санек в 23 декабря 2011 - 14:29 in Геометрия

Определить, лежит ли точка М в круге

Входные данные

5 чисел - mx,my - координаты точки М, xc,yc - координаты центра круга, r - радиус круга

Выходные данные

Вывести "точка М лежит в круге" если это так или "точка М лежит вне круга"


Решение

var xc,yc,mx,my,d,r:real;
begin
readln( mx,my,xc,yc,r ); //mx,my - координаты точки M, xc,yc,r - координаты круга и его радиус
d:=sqrt(sqr(xc-mx)+sqr(yc-my));
if d<=r then writeln ('точка M лежит в круге')
      	else writeln ('точка M лежит вне круга');
end.



#30 Различные элементы

Отправлено от Санек в 22 декабря 2011 - 10:50 in Одномерные массивы

Вводятся число n. Далее идут n чисел. Найти количество различных чисел.

Входные данные

Сначала вводится n - количество чисел (n<=1000). Далее идут n чисел.

Выходные данные

Число - ответ на задачу.

Решение

var a:array[1..1000] of integer;
    i,j,n:integer;
begin
readln(n); //ввод количества элементов
for i:=1 to n do  //ввод элементов массива
  read(a[i]);
i:=1; 
while (i<10) and (j<n+1) do //подсчет количества различных элементов
  begin
   j:=i+1;
   while (j<n+1) and (a[i]<>a[j]) do
    j:=j+1;
   i:=i+1;
  end;
if i<11 then writeln('В массиве ',i,' одинаковых элементов')
          else writeln('Все элементы массива различны');
end.



#53 Максимальная подпоследовательность

Отправлено от Санек в 23 декабря 2011 - 19:10 in Динамическое программирование

Дана числовая последовательность, вывести длину максимальной возрастающей подпоследовательности.

Входные данные

В первой строке вводится n (1<=n<=1000) - длина последовательности. Далее идет сама последовательность длиной n чисел (все числа по модуля не превосходят 10000).

Выходные данные

Одно число - ответ на задачу.

Решение

var a,f:array [1..10000]of longint;
	n,i,max,j:longint;
begin
readln(n); //читаем кол-во чисел
for i:=1 to n do
  read(a[i]); //считываем последовательность
for i:=1 to n do
  f[i]:=1; //забиваем массив ответов 1
for i:=1 to n do
  for j:=1 to i-1 do
   if (a[i]>a[j]) and (f[j]+1>f[i]) then f[i]:=f[j]+1; //ищем длину возрастающей последовательности на каждом шаге последовательности
for i:=1 to n do
  if f[i]>max then max:=f[i]; //находим максимальную подпоследовательность в массиве ответов
writeln(max);
end.



#54 Мячик на лестнице

Отправлено от Санек в 23 декабря 2011 - 19:18 in Динамическое программирование

На вершине лесенки, состоящей из n ступенек, лежит мячик. Он начинает прыгать вниз, к основанию лесенки. Мячик может прыгнуть на след. ступеньку, на ступеньку через одну или через две. Т.е. если мячик лежит на 10 ступеньке, то он может прыгнуть на 9, 8 или 7 ступеньки. Определите число всевозможных маршрутов мячика.

Входные данные

Число n - кол.во ступенек (0<=n<=70)

Выходные данные

Одно число - ответ на задачу

Решение

var f:array [1..70] of int64; i,n:longint;
begin
readln(n); //считываем число ступенек
f[1]:=1; //если у нас 1 ступенька, то кол-во способов 1, т.к. есть один способ сигануть с вершины лесенки до основания, если всего одна ступенька (проверьте сами)
f[2]:=2; //если у нас 2 ступеньки, то кол-во способов 2, т.к. есть два способа сигануть с вершины лесенки до основания, если всего две ступеньки (проверьте сами)
f[3]:=4; //если у нас 3 ступеньки, то кол-во способов 4, т.к. есть четыре способа сигануть с вершины лесенки до основания, если всего три ступеньки (проверьте сами)
for i:=4 to n do
  f[i]:=f[i-2]+f[i-1]+f[i-3]; //А дальше динамика. В массив ответов заносим сумму вариантов "сигания" с i-1, i-2, i-3 ступенек.
writeln(f[n]); //ответ на задачу
end.



#261 Дерево отрезков

Отправлено от Санек в 14 ноября 2012 - 12:45 in Структуры данных

Дерево отрезков — это структура данных, которая позволяет эффективно (т.е. скорость алгоритма (O(log n)) реализовать операции следующего вида:
  • Нахождение суммы на отрезке [L;R]
  • Нахождение минимума и максимума на отрезке [L;R]
  • Изменение элементов (увеличение и уменьшение) на отрезке [L;R]
Вообще, дерево отрезков — очень гибкая структура, и число задач, решаемых ей, теоретически неограниченно. Помимо приведённых выше видов операций с деревьями отрезков, также возможны и гораздо более сложные операции. Но об этом позже.



Важной особенностью деревьев отрезков является то, что они потребляют линейный объём памяти: стандартному дереву отрезков требуется порядка 4n элементов памяти для работы над массивом размера n.

Например в задаче n<=100000. Значит нам надо сделать массив [0..400000].

Структура дерева

Подсчитаем и запомним сумму элементов всего массива, т.е. отрезка a[0..n-1] Также посчитаем сумму на двух половинках этого массива: a[0..n/2] и a[n/2..n-1]. Каждую из этих двух половинок в свою очередь разобьем пополам, посчитаем и сохраним сумму на них, потом снова разобьем пополам, и так далее, пока текущий отрезок не достигнет длины 1. Иными словами, мы стартуем с отрезка [0..n-1] и каждый раз делим текущий отрезок надвое (если он ещё не стал отрезком единичной длины), вызывая затем эту же процедуру от обеих половинок; для каждого такого отрезка мы храним сумму чисел на нём.

Можно говорить, что эти отрезки, на которых мы считали сумму, образуют дерево: корень этого дерева — отрезок [0..n-1], а каждая вершина имеет ровно двух сыновей (кроме вершин-листьев, у которых отрезок имеет длину 1).

Задача


Реализуйте структуру данных, хранящую информацию об N (1 ≤ N ≤ 100000) целых числах A1, ..., AN. Структура должна поддерживать следующие операции.



1) INIT(N) Инициализация числом N. При этом каждому числу Ai присваивается значение 0.

2) MODIFY(pos,value) Значение Apos увеличивается на value, если value ≥ 0, и уменьшается на |value|, если value < 0.

3) FINDSUM(l,r) Вывод в выходной файл суммы a[l]..a[r].



Input

Входной файл содержит не более 100000 операций. Каждая операция описывается в отдельной строке. Описание операции начинается с целого числа от 1 до 3 --- ее номера в списке выше. Далее следуют параметры операции в порядке их перечисления в скобках. Числа в каждой строке разделены пробелами.

Все операции корректны. Это значит, что:
  • операция INIT является самой первой операцией во входном файле и больше нигде в нем не встречается;
  • для операции MODIFY выполняются ограничения 1 ≤ pos ≤ N и -10000 ≤ value ≤ 10000;
  • для операции FINDSUM выполняются ограничения 1 ≤ l ≤ r ≤ N.
Output




Выполните операции в порядке их перечисления в входном файле. Если для выполнения операции нужно вывести некоторую информацию в выходной файл, то выведите эту информацию. Вывод для каждой операции оформите в отдельной строке.

Ввод

1 5
2 4 3
2 2 2
3 2 3
2 5 -2
3 2 4
2 5 6
2 4 2
3 3 3
2 1 -8
2 5 -3
2 4 -7
2 5 -4
3 4 4
3 1 2

Вывод

2
5
0
2
6

Решение

Совершенно очевидно, что надо применять дерево отрезков для решения этой задачи. Каждый из запросов задается первым числом в строке входного файла. Т.е. если нам ввели 1, то надо выполнить запрос INIT, если ввели 2, то надо выполнить запрос MODIFY, если 3, то запрос FINDSUM. Итак рассмотрим каждый из запросов в отдельности.

Запрос INIT(N)

Здесь нам надо обнулить всё дерево, т.е. построить его. Для этого сделаем вот что:

Прочитаем число n. Далее подберем такой показатель степени (банально мы подбираем число), чтобы при возведении 2 в эту степень полученное число было больше нашего n. Это и будет размером нашего массива для хранения дерева сумм. Ну и обнуляем все a[i].

Запрос MODIFY(pos,value)

Этот запрос получает на вход индекс pos и значение value, и перестраивает дерево отрезков таким образом, чтобы оно соответствовало новому значению a[pos]=value .
Тогда понятно, что запрос обновления можно реализовать как рекурсивную функцию: ей передается текущая вершина дерева отрезков, и эта функция выполняет рекурсивный вызов от одного из двух своих сыновей (от того, который содержит позицию pos в своем отрезке), а после этого — пересчитывает значение суммы в текущей вершине точно таким же образом, как мы это делали при построении дерева отрезков (т.е. как сумма значений по обоим сыновьям текущей вершины).

Запрос FINDSUM(l,r)

Реализация

Построение

 
procedure init;
begin
  readln(n);
  pr:=1;
  while pr<n do
    pr:=pr*2;
end;
 


Обновление

 
procedure modify(p,v:longint);
begin
  a[p]:=a[p]+v;
  if p<>1 then modify(p div 2,v);
end;
 


Нахождение суммы

 
procedure findsum(v,l,r:longint);
begin
  if (lv>r) or (rv<l)
    then exit
      else
        if (l>=lv) and (rv>=r)
          then s:=s+a[v]
            else
              begin
                findsum(2*v,l,(l+r)div 2);
                findsum(2*v+1,(l+r)div 2+1,r);
              end;
end;


В основном коде делаем вот что

 
читаем b
      if b=1 then init;
      if b=2
        then
          begin
            readln(p,v);
            p:=pr+p-1;
            modify(p,v);
          end;
      if b=3
        then
          begin
            readln(lv,rv);
            lv:=pr+lv-1;
            rv:=pr+rv-1;
            findsum(1,pr,2*pr-1);
            writeln(s);
            s:=0;
          end;
    end;



#26 Сумма элементов двумерного массива

Отправлено от Санек в 22 декабря 2011 - 10:15 in Двумерные массивы

Дана матрица n*m . Найти сумму всех элементов этой матрицы.

Входные данные

n,m - размеры матрицы (n,m<=100). Далее в n столбцах и m строках следуют элементы матрицы a[i,j]

Выходные данные

Одно число - сумма всех элементов

Ввод

2 3

1 3 4
2 6 3

Вывод

19

Решение

var a:array[1..100,1..100] of longint;
	s,n,m,i,j:longint;   
begin
readln(n,m);
s:=0;
for i:=1 to n do
  for j:=1 to m do
   read(a[i,j]);
for i:=1 to n do
  for j:=1 to m do
	s:=s+a[i,j];
writeln(s);
end.



#25 Пересечение окружностей

Отправлено от Санек в 22 декабря 2011 - 09:33 in Геометрия

Задача Пересечение окружностей


Задан набор из N окружностей, которые описываются координатами своих центров. Все окружности имеют одинаковый радиус R. Необходимо найти две окружности, площадь пересечения которых максимальная. На рисунке красным цветом отображается область пересечения двух окружностей.

Изображение

Формат ввода:

N R
X[1] Y[1]
X[2] Y[2]

X[N] Y[N]

N – Количество окружностей
R – Радиус окружностей
X[i] Y[i] – центр i-ой окружности

Ограничения:

2 <= N < = 100
0 <= X[i] Y[i] R <= 1000
Все числа целые.

Формат вывода:

Ответ на задачу - номера окружностей, площадь пересечения которых максимальная.

Пример ввода:

3 1
0 0
1 0
1 1

Пример вывода:

1 2

Программный код.

var x,y:array[1..1000] of longint; n,i,r,n2,n1,j:longint; minp,p:real;
begin
readln(n,r);
for i:=1 to n do
  readln(x[i],y[i]);
minp:=sqrt( (x[1]-x[2])*(x[1]-x[2])+(y[1]-y[2])*(y[1]-y[2]) );
n1:=1;
n2:=2;
for i:=1 to n do
  for j:=1 to n do
   begin
	p:=sqrt( (x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]) );
	if (minp >p)and(i<>j) then begin
                            	minp:=p;
                            	n1:=i;
                            	n2:=j;
                           	end;
   end;
writeln(n1,' ',n2);
end.




#21 Простое число

Отправлено от Санек в 22 декабря 2011 - 09:06 in Целочисленная арифметика

Просто́е число́ — это натуральное число, имеющее ровно два различных натуральных делителя: единицу и самого себя. Все остальные числа, кроме единицы, называются составными. Таким образом, все натуральные числа больше единицы разбиваются на простые и составные. Изучением свойств простых чисел занимается теория чисел. В теории колец простым числам соответствуют неприводимые элементы.

Последовательность простых чисел начинается так:
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, …

Функция простого числа на паскале

function pr(x:longint):boolean;
var d:longint;
begin
if x mod 2 =0 then pr:=(x=2)
          	else
          	begin
  d:=3;
  while (d*d<=x)and(x mod d <>0) do
  d:=d+2;
  pr:=(d*d>x)and(x<>1);
end;
end;



Пример задачи с использованием простых чисел.

Задача

Вывести все простые числа от M до N включительно.

Ограничения: 2 <= M <= N <= 300 000.

Ввод: В первой строке находятся разделённые пробелом M и N.

Вывод: Вывести числа в порядке возрастания, по одному в строке. Если между M и N включительно нет простых - вывести "Absent".

Примеры

Ввод 1

2 5

Вывод 1

2

3

5

var n,m,i,f:LONGINT;
function pr(x:longint):boolean;
var d:longint;
begin
if x mod 2 =0 then pr:=(x=2)
          	else
          	begin
  d:=3;
  while (d*d<=x)and(x mod d <>0) do
  d:=d+2;
  pr:=(d*d>x)and(x<>1);
end;
end;
begin
f:=0;
readln(n,m);
for i:=n to m do
if pr(i) then begin writeln(i); f:=1; end;
if f=0 then writeln('Absent');
end.




#22 Сортировка пузырьком

Отправлено от Санек в 22 декабря 2011 - 09:13 in Сортировка и перебор

Сортиро́вка пузырько́м (англ. bubble sort) — простой алгоритм сортировки. Для понимания и реализации этот алгоритм — простейший, но эффективен он лишь для небольших массивов. Сложность алгоритма: O(n²).
Алгоритм считается учебным и практически не применяется вне учебной литературы, вместо него на практике применяются более эффективные алгоритмы сортировки. В то же время метод сортировки обменами лежит в основе некоторых более совершенных алгоритмов, таких как шейкерная сортировка, сортировка Шелла и быстрая сортировка.

Пример работа алгоритма



Возьмём массив с числами «5 1 4 2 8» и отсортируем значения по возрастанию, используя сортировку пузырьком. Выделены те элементы, которые сравниваются на данном этапе.

Первый проход:

(5 1 4 2 8) (1 5 4 2 8), Здесь алгоритм сравнивает два первых элемента и меняет их местами.

(1 5 4 2 8) (1 4 5 2 8), Меняет местами, так как 5 > 4

(1 4 5 2 8) (1 4 2 5 8), Меняет местами, так как 5 > 2

(1 4 2 5 8) (1 4 2 5 8), Теперь, ввиду того, что элементы стоят на своих местах (8 > 5), алгоритм не меняет их местами.

Второй проход:

(1 4 2 5 8) (1 4 2 5 8)

(1 4 2 5 8) (1 2 4 5 8), Меняет местами, так как 4 > 2

(1 2 4 5 8) (1 2 4 5 8)

(1 2 4 5 8) (1 2 4 5 8)



Теперь массив полностью отсортирован, но алгоритм не знает так ли это. Поэтому ему необходимо сделать полный проход и определить, что перестановок элементов не было.

Третий проход:

(1 2 4 5 8) (1 2 4 5 8)

(1 2 4 5 8) (1 2 4 5 8)

(1 2 4 5 8) (1 2 4 5 8)

(1 2 4 5 8) (1 2 4 5 8)



Теперь массив отсортирован и алгоритм может быть завершён.

Программный код

var a:array[1..10000] of integer;
	i,j,x,n:integer;
begin
  readln(n);   
  writeln('введите ',n,' элементов массива');
  for i:=1 to n do
   read( a[i] );
  for i:=1 to n-1 do
   for j:=1 to n-i do
	if a[j]>a[j+1] then begin
                     	x:=a[j];
                     	a[j]:=a[j+1];
                     	a[j+1]:=x;
                    	end;
writeln('после сортировки:');
for i:=1 to n do
  write( a[i],' ' );
end.



#23 Сортировка пузырьком

Отправлено от Санек в 22 декабря 2011 - 09:14 in Сортировка

Сортиро́вка пузырько́м (англ. bubble sort) — простой алгоритм сортировки. Для понимания и реализации этот алгоритм — простейший, но эффективен он лишь для небольших массивов. Сложность алгоритма: O(n²).
Алгоритм считается учебным и практически не применяется вне учебной литературы, вместо него на практике применяются более эффективные алгоритмы сортировки. В то же время метод сортировки обменами лежит в основе некоторых более совершенных алгоритмов, таких как шейкерная сортировка, сортировка Шелла и быстрая сортировка.

Пример работа алгоритма



Возьмём массив с числами «5 1 4 2 8» и отсортируем значения по возрастанию, используя сортировку пузырьком. Выделены те элементы, которые сравниваются на данном этапе.

Первый проход:

(5 1 4 2 8) (1 5 4 2 8), Здесь алгоритм сравнивает два первых элемента и меняет их местами.

(1 5 4 2 8) (1 4 5 2 8), Меняет местами, так как 5 > 4

(1 4 5 2 8) (1 4 2 5 8), Меняет местами, так как 5 > 2

(1 4 2 5 8) (1 4 2 5 8), Теперь, ввиду того, что элементы стоят на своих местах (8 > 5), алгоритм не меняет их местами.

Второй проход:

(1 4 2 5 8) (1 4 2 5 8)

(1 4 2 5 8) (1 2 4 5 8), Меняет местами, так как 4 > 2

(1 2 4 5 8) (1 2 4 5 8)

(1 2 4 5 8) (1 2 4 5 8)



Теперь массив полностью отсортирован, но алгоритм не знает так ли это. Поэтому ему необходимо сделать полный проход и определить, что перестановок элементов не было.

Третий проход:

(1 2 4 5 8) (1 2 4 5 8)

(1 2 4 5 8) (1 2 4 5 8)

(1 2 4 5 8) (1 2 4 5 8)

(1 2 4 5 8) (1 2 4 5 8)



Теперь массив отсортирован и алгоритм может быть завершён.

Программный код

var a:array[1..10000] of integer;
	i,j,x,n:integer;
begin
  readln(n);  
  writeln('введите ',n,' элементов массива');
  for i:=1 to n do
   read( a[i] );
  for i:=1 to n-1 do
   for j:=1 to n-i do
	if a[j]>a[j+1] then begin
                 		x:=a[j];
                 		a[j]:=a[j+1];
                 		a[j+1]:=x;
                    	end;
writeln('после сортировки:');
for i:=1 to n do
  write( a[i],' ' );
end.



#24 Сортировка матрицы n*m

Отправлено от Санек в 22 декабря 2011 - 09:16 in Сортировка и перебор


Задана матрица A размера NxM. Вам необходимо отсортировать числа в каждой строке матрицы в порядке возрастания.

Формат ввода:

В первой строке находятся числа N и M. Далее следует описание самой матрицы - N строк по M чисел в каждой.

Ограничения:

1 <= N, M <= 100
-100 <= A[i,j] <= 100

Формат вывода:

Ответ на задачу - исходная матрица, каждая строка которой отсортирована по возрастанию.

Пример ввода:

3 4
1 2 3 4
4 3 2 1
4 1 3 2

Пример вывода:

1 2 3 4
1 2 3 4
1 2 3 4

Здесь применяется метод быстрой сортировки

var a:array [1..1000] of longint; n,m,i,j:longint;
procedure qsort(l,r:longint);
var i,j,x,p:longint;
begin
i:=l;
j:=r;
x:=a[(i+j)div 2];
repeat
  while a[i]<x do i:=i+1;
  while a[j]>x do j:=j-1;
  if i<=j then begin
            	p:=a[i];
            	a[i]:=a[j];
            	a[j]:=p;
            	i:=i+1;
            	j:=j-1;
   			end;
until i>j;
if i<r then qsort(i,r);
if j>l then qsort(l,j);
end;
begin
readln(n,m);
for i:=1 to n do
  begin
   for j:=1 to m do
	read(a[j]);
	qsort(1,m);
   for j:=1 to m do
	write(a[j],' ');
   writeln;
end;
end.




#18 Решето Эратосфена

Отправлено от Санек в 22 декабря 2011 - 08:59 in Целочисленная арифметика

Решето́ Эратосфе́на — алгоритм нахождения всех простых чисел до некоторого целого числа n, который приписывают древнегреческому математику Эратосфену.

Алгоритм

Для нахождения всех простых чисел не больше заданного числа n, следуя методу Эратосфена, нужно выполнить следующие шаги:



Выписать подряд все целые числа от двух до n (2, 3, 4, …, n).

Пусть переменная p изначально равна двум — первому простому числу.

Считая от p шагами по p, зачеркнуть в списке все числа от 2p до n кратные p (то есть числа 2p, 3p, 4p, …)

Найти первое не зачеркнутое число, большее чем p, и присвоить значению переменной p это число.

Повторять шаги 3 и 4 до тех пор, пока p не станет больше, чем n

Теперь все не зачеркнутые числа в списке — простые.

На практике, алгоритм можно несколько улучшить следующим образом. На шаге № 3, числа можно зачеркивать, начиная сразу с числа p2, потому что все составные числа меньше его уже будут зачеркнуты к этому времени. И, соответственно, останавливать алгоритм можно, когда p2 станет больше, чем n.

Можно показать, что сложность алгоритма составляет O(nlog log n) операций в модели вычислений RAM, или O(n(log n)(log log n)) битовых операций, при условии вычисления и зачеркивания каждого кратного числа за время O(1), например при использования массивов с прямым доступом.



http://upload.wikime...ratosthenes.gif



Программный код


var b:array[2..100000] of boolean;
i,j,n:longint;
begin
readln(n);
for i:=2 to n do b[i]:= true;
i:=2;
while i*i<= n do begin
if b[i]= true then begin
       			j:=i*i;
       			while j<=n do begin
                     			b[j]:=false;
                     			j:=j+i;
                     			end;
       			end;
if i=2 then i:=3 else i:=i+2;
end;
for i:=2 to n do
if b[i] then write(i,' ');
end.