Разработать программу turbo pascal, выполняющую перевод действительного числа X заданного в системе счисления с основанием q в систему счисления с основанием p (2≤ q,p ≤16)
Const n = 20; { размер массивов } p=0; { минимальное значение элемента } q=15; { максимальное значение элемента } type V=array[1..n] of integer;
procedure VInit(var a:V; s:string); { процедура заполняет элементы массива a случайными значениями из интервала [p;q]. Элементы сформированного массива выводятся с заголовком, в который добавляется значение s } var i,kol:integer; begin kol:=q-p+1; Writeln('Элементы массива ',s); for i:=1 to n do begin a[i]:=Random(kol)+p; Write(a[i],' ') end; Writeln end;
procedure SortBubble(var a:V); { сортировка методом пузырька } var i,j,t:integer; begin for i := 1 to n-1 do for j := 1 to n-i do if a[j] > a[j+1] then begin t := a[j]; a[j] := a[j+1]; a[j+1] := t end end;
procedure VOut(var a:V;s:string); { Элементы массива a выводятся с заголовком s } var i:integer; begin Writeln(s); for i:=1 to n do Write(a[i],' '); Writeln end;
function BinSearch(var a:V;key:integer):boolean; { двоичный поиск элемента со значением key в массиве a Возвращает true, если элемент найден и false, если нет } var li,ri,mi:integer; begin li:=1; ri:=n; while li<ri do begin mi:=(li+ri) div 2; if a[mi]<key then li:=mi+1 else ri:=mi; end; BinSearch:=(a[ri]=key) end;
var a,b,c:V; i,ai1,s:integer; found:boolean; begin Randomize; VInit(a,'A'); SortBubble(a); VOut(a,'Отсортированный массив A'); VInit(b,'B'); SortBubble(b); VOut(b,'Отсортированный массив B'); VInit(c,'C'); SortBubble(c); VOut(c,'Отсортированный массив C'); s:=0; found:=false; for i:=1 to n do begin if found then if a[i]=ai1 then Inc(s,ai1) else found:=false; if not found then begin found:=BinSearch(b,a[i]); if found then found:=BinSearch(c,a[i]); if found then begin ai1:=a[i]; Inc(s,ai1) end end end; Writeln('Искомая сумма равна ',s); end.
Это задача совсем не "за ". Количество чисел k2, которые делятся на два, равно целой части от n/2. Аналогично, k3=n/3 и k5/n/5. Вычтем все эти количества из общего количества чисел, равного n: k=n-(k2+k3+k5) и это даст примерное количество чисел, которые не делятся на 2, 3 и 5. Примерно оно потому, что мы не учли числа, которые одновременно делятся на 2 и 3, на 2 и 5, на 3 и 5. Т.е. числа, которые делятся на 6, 10 и 15 мы вычли дважды. Поэтому надо найти количество этих чисел и отнять их. k6=n/6, k10=n/10, k15=n/15 - по-прежнему делим нацело. И теперь за исправленное значение k принимаем k+(k6+k10+k15). И последнее. Есть еще числа, которые делятся одновременно на 2, 3 и 5, т.е. на 2*3*5=30. Таких чисел k30=n/30. И мы их дважды прибавили. Теперь делаем последнюю коррекцию k, получая : k-k30.
Окончательно формула расчета: k=n-(k/2+k/3+k/5)+(k/6+k/10+k/15)-k/30 при условии целочисленного деления.
То что мы проделали выше, носит название операции включения-исключения множеств. Программа получается совсем простой.
Sub abc() Dim n As Long n = InputBox("Введите натуральное N") If n < 0 Then n = Abs(n) 'Защита от дурака MsgBox n - (n \ 2 + n \ 3 + n \ 5) + (n \ 6 + n \ 10 + n \ 15) - n \ 30 End Sub
n = 20; { размер массивов }
p=0; { минимальное значение элемента }
q=15; { максимальное значение элемента }
type
V=array[1..n] of integer;
procedure VInit(var a:V; s:string);
{ процедура заполняет элементы массива a
случайными значениями из интервала [p;q].
Элементы сформированного массива выводятся
с заголовком, в который добавляется значение s }
var
i,kol:integer;
begin
kol:=q-p+1;
Writeln('Элементы массива ',s);
for i:=1 to n do
begin a[i]:=Random(kol)+p; Write(a[i],' ') end;
Writeln
end;
procedure SortBubble(var a:V);
{ сортировка методом пузырька }
var
i,j,t:integer;
begin
for i := 1 to n-1 do
for j := 1 to n-i do
if a[j] > a[j+1] then
begin t := a[j]; a[j] := a[j+1]; a[j+1] := t end
end;
procedure VOut(var a:V;s:string);
{ Элементы массива a выводятся с заголовком s }
var
i:integer;
begin
Writeln(s);
for i:=1 to n do Write(a[i],' ');
Writeln
end;
function BinSearch(var a:V;key:integer):boolean;
{ двоичный поиск элемента со значением key в массиве a
Возвращает true, если элемент найден и false, если нет }
var
li,ri,mi:integer;
begin
li:=1; ri:=n;
while li<ri do begin
mi:=(li+ri) div 2;
if a[mi]<key then li:=mi+1 else ri:=mi;
end;
BinSearch:=(a[ri]=key)
end;
var
a,b,c:V;
i,ai1,s:integer;
found:boolean;
begin
Randomize;
VInit(a,'A'); SortBubble(a); VOut(a,'Отсортированный массив A');
VInit(b,'B'); SortBubble(b); VOut(b,'Отсортированный массив B');
VInit(c,'C'); SortBubble(c); VOut(c,'Отсортированный массив C');
s:=0; found:=false;
for i:=1 to n do
begin
if found then
if a[i]=ai1 then Inc(s,ai1)
else found:=false;
if not found then begin
found:=BinSearch(b,a[i]);
if found then found:=BinSearch(c,a[i]);
if found then begin ai1:=a[i]; Inc(s,ai1) end
end
end;
Writeln('Искомая сумма равна ',s);
end.
Тестовое решение:
Элементы массива A
4 10 6 4 12 5 5 15 0 14 2 2 0 3 14 1 11 13 3 9
Отсортированный массив A
0 0 1 2 2 3 3 4 4 5 5 6 9 10 11 12 13 14 14 15
Элементы массива B
7 3 13 3 10 11 3 15 12 10 0 5 5 15 13 1 15 9 1 5
Отсортированный массив B
0 1 1 3 3 3 5 5 5 7 9 10 10 11 12 13 13 15 15 15
Элементы массива C
4 10 5 8 14 15 8 14 12 4 12 12 3 11 4 0 12 2 10 0
Отсортированный массив C
0 0 2 3 4 4 4 5 8 8 10 10 11 12 12 12 12 14 14 15
Искомая сумма равна 64
Количество чисел k2, которые делятся на два, равно целой части от n/2. Аналогично, k3=n/3 и k5/n/5. Вычтем все эти количества из общего количества чисел, равного n: k=n-(k2+k3+k5) и это даст примерное количество чисел, которые не делятся на 2, 3 и 5. Примерно оно потому, что мы не учли числа, которые одновременно делятся на 2 и 3, на 2 и 5, на 3 и 5. Т.е. числа, которые делятся на 6, 10 и 15 мы вычли дважды. Поэтому надо найти количество этих чисел и отнять их. k6=n/6, k10=n/10, k15=n/15 - по-прежнему делим нацело. И теперь за исправленное значение k принимаем k+(k6+k10+k15).
И последнее. Есть еще числа, которые делятся одновременно на 2, 3 и 5, т.е. на 2*3*5=30. Таких чисел k30=n/30. И мы их дважды прибавили. Теперь делаем последнюю коррекцию k, получая : k-k30.
Окончательно формула расчета:
k=n-(k/2+k/3+k/5)+(k/6+k/10+k/15)-k/30 при условии целочисленного деления.
То что мы проделали выше, носит название операции включения-исключения множеств.
Программа получается совсем простой.
Sub abc()
Dim n As Long
n = InputBox("Введите натуральное N")
If n < 0 Then n = Abs(n) 'Защита от дурака
MsgBox n - (n \ 2 + n \ 3 + n \ 5) + (n \ 6 + n \ 10 + n \ 15) - n \ 30
End Sub