Форум программистов, компьютерный форум, киберфорум
Free Pascal
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/11: Рейтинг темы: голосов - 11, средняя оценка - 5.00
1 / 1 / 0
Регистрация: 03.08.2018
Сообщений: 27

Мобильные телефоны

25.03.2020, 17:40. Показов 2519. Ответов 10

Студворк — интернет-сервис помощи студентам
В области Тампере существуют станции обслуживания мобильных телефонов четвертого поколения, которые работают следующим образом. Вся область разделена на квадраты. Квадраты формируют матрицу S×S, строки и столбы которой нумеруются с 0 до S−1. Каждый квадрат содержит одну станцию обслуживания. Количество активных мобильных телефонов внутри квадрата может меняться, потому что телефон может перемещаться из одного квадрата в другой или выключаться. Временами каждая станция обслуживания передает сведения об изменении в количестве активных телефонов на главную станцию обслуживания (вместе с номером строки и столбца матрицы).

Напишите программу, которая принимает эти сведения и отвечает на запросы о текущем количестве активных мобильных телефонов в любой прямоугольной области.

Формат входных данных
Каждый запрос к программе задан на отдельной строке и состоит из одного целого числа, описывающего команду, и последовательности чисел, являющиеся параметрами команды.
Команда Параметры Значение
0 S Инициализирует матрицу размером S×S, состоящую только из нулей. Эта команда поступает один раз и является самой первой командой.
1 XYA Добавить число A к количеству активных мобильных телефонов в квадрате (X; Y). Число A может быть как положительным, так и отрицательным.
2 LBRT Выдать текущую сумму количеств активных мобильных телефонов во всех квадратах (X; Y), таких что L≤X≤R, B≤Y≤T.
3 ∅ Означает конец входных данных. Эта команда поступает ровно один раз и является самой последней командой.
S не превосходит 1024, количество команд — 60002, значение ячейки в любой момент времени — 215, количество активных телефонов во всей таблице — 230. Величина обновления не превосходит по модулю 215, также ни в один момент времени число активных телефонов в квадрате не становится меньше нуля.

Все индексы нумеруются начиная с нуля.

Формат выходных данных
На запросы типов 0, 1, 3 отвечать не надо. Для каждого запроса второго типа выведите строку, содержащую одно целое число — ответ на него.
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
const max_size = 1023;
var table:array[0..max_size, 0..max_size] of longint;
N, size, cmd, a1, a2, a3, a4:longint;
 
function disp (x:longint):longint;
begin 
 disp := x and (x xor (x - 1));
end;
 
procedure
update (x, y, amount:longint);
 
var ix:longint;
 
begin
inc (x);
inc (y);
 
while y <= size do
  begin 
    ix:= x;
  while ix <=size
  do
    begin inc (table[ix - 1, y - 1], amount);
  inc (ix, disp (ix)) end;
     inc (y, disp (y)) end end;
 
     function sum (x, y:longint):longint;
     var res, ix, iy:longint;
     begin res := 0;
iy:= y + 1;
  while iy
    >0
    do
 
    begin ix:= x + 1;
 
    while ix
    >0
    do
 
      begin inc (res, table[ix - 1, iy - 1]);
 
    dec (ix, disp (ix)) end;
 
    dec (iy, disp (iy)) end;
 
  sum:= res end;
 
BEGIN 
repeat read (cmd);
case cmd of 0:
    begin read (n);
  size:= 1;
    while size<n
      do
      size:= size shl 1 end;
 
    1:begin read (a1, a2, a3);
 
      update (a1, a2, a3) end;
 
    2:begin read (a1, a2, a3, a4);
 
     writeln (sum (a3, a4) - sum (a1 - 1, a2) - sum (a1, a2 - 1) +
           sum (a1 - 1, a2 - 1)) end end until cmd = 3 
END.
Написал такой код, но большая часть тестов проваливается. Прошу найти ошибки, либо привести свое решение. Подробные объяснения приветствуются
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
25.03.2020, 17:40
Ответы с готовыми решениями:

Мобильные телефоны
Ребят, помогите. Возникла проблему, которую нужно срочно решить: в общем, телефон не видит дополнительную карту памяти. На ней остались...

Верстка под мобильные телефоны
Доброе врямя суток! Друзья, подскажите пожалуйства на счет верстки под мобильные устройства. Прочитал множество сайтов. Смысл...

Насколько долговечны мобильные телефоны и смартфоны
Доброго времени суток. Коллекционирую мобильные телефоны и немного смартфоны. Задался вопросом, насколько долго могут прожить мобильники...

10
445 / 373 / 133
Регистрация: 09.09.2011
Сообщений: 1,343
26.03.2020, 22:21
написать сначала "простой" код, который проходит тесты, потом занимать оптимизацией не пойми чего с побитовыми операциями.

Эта же задача не требует никакой хитрой алгоритмики, просто аккуратно записать логику в код.

что у Вас делает функция disp? зачем?

я практически уверен, если написать код "в лоб", без каких либо оптимизаций, то потом улучшить его по скорости на какие-то заметные значения не получится, максимум сэкономить немного памяти.


Приведите открытый тест который дают к заданию. вход - корректный вывод.
0
1 / 1 / 0
Регистрация: 03.08.2018
Сообщений: 27
27.03.2020, 01:13  [ТС]
Задача сложна для меня тем, что в ней требуется особенная оптимизация, т.к кол-во команд может быть очень большое. Самый первые 3 теста у меня проходят, остальные уже нет.

Решение этой задачи проще понять для одномерного варианта, то есть для матрицы 1 x N. Ответ на запрос о количестве телефонов в некотором интервале [X, Y] можно получить следующим образом: S xy = S y — S x—1 , S y — количество телефонов на интервале [0, Y], а S x—1 — на интервале [0, X—1].

А если вспомогательные суммы хранить в виде дерева, то обновлять их можно за O(logN) операций. Хранить дерево можно с помощью одномерного массива из N элементов, индексы которого удобно обозначать от 1 до N. I-й элемент такого массива содержит сумму элементов исходного массива на интервале [I—2k , I—1], где за k мы всегда будем обозначать число нулей в конце двоичного представления индекса элемента вспомогательного массива. Например, в четвертом элементе вспомогательного массива хранится сумма элементов с 0-го по 3-й исходного массива, так как 4 = 1002 , то есть два нуля в конце двоичного представления, и I — 2k = 4 — 22 = 0. Вот логика этой функции disp - для x получает соответствующие 2^k
0
445 / 373 / 133
Регистрация: 09.09.2011
Сообщений: 1,343
27.03.2020, 14:26
так тесты не проходят по времени? а какой лимит?

Добавлено через 24 минуты
вот такой тест не проходит:

0 10
1 9 9 1
1 3 3 5
1 0 0 1
1 0 3 1
2 9 1 9 9
3

должно быть 1, выдает 7

Добавлено через 2 часа 41 минуту
мне кажется, что если функции update и sum записаны корректно (что похоже), то скорее всего логика в строке 65 не верная.

если функция sum возвращает сумму всех активных телефонов в ячейках от текущей до самой 1-ой ячейки, то логика должна быть такая:

если прямоугольная область, переданная в команде 2, находится в одной строке, либо ширина этой области равна S - то берем сумму от конца области и вычитаем сумму от начала
во всех дургих случаях нужен цикл по количеству столбцов где считаем общую сумму из разности сумм конца - начала каждой строки.
0
1 / 1 / 0
Регистрация: 03.08.2018
Сообщений: 27
27.03.2020, 16:32  [ТС]
Вот, именно, что я и не знаю, как обстоят дела с оптимизацией, т.к тестирующая система еще не дошла до длинных тестов. Крашится уже на 4ом. Постараюсь разобраться тогда в ваших словах. Лимит исполнения программы - 1 секунда
0
445 / 373 / 133
Регистрация: 09.09.2011
Сообщений: 1,343
29.03.2020, 16:48
а на какой системе ты тестируешь? обычно же пишут в чем ошибка - либо превышение по времени/памяти, либо не верный ответ.

я не очень понял логику с размером матрицы с суммами, судя по объяснению, то размер должен совпадать с размером входной матрицы активных телефонов (вернее вышек), но в программе размер матрицы будет степень 2-ки большая чем входное значение? так и должно быть? например при входе S=10, size = 16
0
1 / 1 / 0
Регистрация: 03.08.2018
Сообщений: 27
29.03.2020, 22:33  [ТС]
Проблема как раз в том, что неверный ответ
0
445 / 373 / 133
Регистрация: 09.09.2011
Сообщений: 1,343
30.03.2020, 01:32
я тут подумал, что можно по другому на задачу посмотреть. По условию максимально 230 активных телефонов, т.е. вместо того чтобы хранить состояние всех "вышек", хранить только те, в которых есть активные телефоны. тогда при подсчете суммы, надо будет 230 итераций (вместо миллиона при решении "в лоб").

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

например взять массив из 230 элементов в котором хранить структуру - X,Y,VALUE

тогда при обновлении - ищем в массиве нужные X,Y и обновляем VALUE, а если не находим, то ищем первую структуру с VALUE=0 и обновляем X,Y и VALUE

при сумме - проходим по массиву и проверяем, входит ли X,Y в нужную область, если да - то прибавляем.

Добавлено через 5 минут
для такого алгоритма еще можно пару частных оптимизаций сделать, например если s*s < 230, то и размер массива хранения уменьшить

при обновлении, при поиске X,Y сразу же искать и запоминать и первую ячейку с VALUE=0, что-бы не искать его в отдельном цикле если понадобится.
1
445 / 373 / 133
Регистрация: 09.09.2011
Сообщений: 1,343
30.03.2020, 13:59
вот набросал решение по 2-му варианту:

Кликните здесь для просмотра всего текста
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
program olimp_task_mob_sol1;
{программа по заданию отсюда https://www.cyberforum.ru/free-pascal/thread2604643.html}
const
  MAX_ACTIVE = 230;
{$DEFINE DEBUG}
type
  TActive = record
    X: integer;     //0..1023 можно поменять на shortInt
    Y: integer;     //0..1023
    Value: integer; //0..230  можно поменять на byte
  end;
 
var
  as_table: array [1..MAX_ACTIVE] of TActive;
  size: integer;  // колличество активных вышек, если s*s < MAX_ACTIVE
 
  procedure update(ax, ay, amount: integer);
  var
    foundZeroVal: boolean = False;
    i, idxZero: integer;
  begin
    for i := 1 to size do
    begin
      if (as_table[i].X = ax) and (as_table[i].Y = ay) then
      begin
        Inc(as_table[i].Value, amount);
        exit;
      end
      else
      if (not foundZeroVal) and (as_table[i].Value = 0) then
      begin
        foundZeroVal := True;
        idxZero := i;
      end;
    end;
    as_table[idxZero].X := ax;
    as_table[idxZero].Y := ay;
    as_table[idxZero].Value := amount;
  end;
 
  function asum(ax1, ay1, ax2, ay2: integer): integer;
  var
    i: integer;
  begin
    Result := 0;
    for i := 1 to size do
      if ((as_table[i].X >= ax1) and (as_table[i].X <= ax2)) and
         ((as_table[i].Y >= ay1) and (as_table[i].Y <= ay2)) then
        Inc(Result, as_table[i].Value);
  end;
var
  cmd, a1, a2, a3, a4: integer;
begin
  {$IFDEF DEBUG}
  Assign(Input, 'input.txt');
  Assign(Output, 'output.txt');
  reset(input);
  Rewrite(output);
  {$ENDIF}
  repeat
    Read(cmd);
    case cmd of
      0:
      begin
        Read(size);
        if size*size > MAX_ACTIVE then
           size:= MAX_ACTIVE
        else
          size *= size;
      end;
 
      1:
      begin
        Read(a1, a2, a3);
 
        update(a1, a2, a3);
      end;
 
      2:
      begin
        Read(a1, a2, a3, a4);
 
        writeln(asum(a1, a2, a3, a4));
      end;
    end;
  until cmd = 3;
  {$IFDEF DEBUG}
  Close(Input);
  Close(Output);
  {$ENDIF}
end.


что-бы заработало на платформе - удали DEFINE DEBUG
1
445 / 373 / 133
Регистрация: 09.09.2011
Сообщений: 1,343
01.04.2020, 17:09
эээ, вроде нашел оригинальное задание тут https://informatics.mccme.ru/m... 2#ch111778

так там указывается, что максимальное количество активных телефонов не 230, а 230, что конечно несколько отличается....

в таком прочтении мое решение не годится, и надо с суммами разбираться.

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

Добавлено через 2 минуты
ну и величина обновления не 215 а 215

Добавлено через 3 часа 30 минут
вот тут мой вариант, по алгоритму из 3-го сообщения. В линейном массиве хранятся суммы с переменным диапазоном. Не уверен что алгоритм эффективен для случая когда у нас столбец во всю матрицу размером в 1024*1024, шириной в 1 элемент. но тем не менее, вроде считает правильно. К сожалению не нашел систему, где можно проверить код.
Кликните здесь для просмотра всего текста
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
program olimp_task_mob_sol2;
{программа по заданию отсюда https://www.cyberforum.ru/free-pascal/thread2604643.html}
{$mode objfpc}{$H+}
{$DEFINE DEBUG}
const
  MAX_SIZE = 1024;
var
  table: array[1..MAX_SIZE*MAX_SIZE] of longint; //массив хранения сумм
  size, cmd, a1, a2, a3, a4:longint;
 
//возвращает 2 в стпенеи количества нулей справа в 2-ичном предствалении x
//например  1= 1, 2=2, 3=1, 4=4 и т.д.
function disp (x: longint): longint;
begin
 disp := x and (x xor (x - 1));
end;
 
procedure update (x, y, amount: longint);
var
  idx: longint;
begin
  idx:= x + size * y; //порядковый номер ячейки в одномерном представлении  [0..1024*1024-1]
  inc(idx);           //увеличем на 1, т.к. суммы хранятся для диапазона в след. ячейке
  while idx <= size*size do begin
    inc (table[idx], amount);
    inc (idx, disp(idx));
  end;
end;
 
function asum(ax1, ay1, ax2, ay2: longint): longint;
  function get_sum(ax: longint ): Longint;
  begin
    Result:= 0;
    if ax = -1 then exit(0); //диапазон перед первым элементом
    //сумма для этого элемента записана в следующей ячейке
    inc(ax);
    while ax >= 1 do begin
      inc (Result, table[ax]);
      dec (ax, disp(ax));
    end;
  end;
var
  i, idx1, idx2: longint;
begin
  Result := 0;
 
  //сначала обрабатываем простой случай, если диапазон области непрерывен
  if (ay1 = ay2) or (ax2 - ax1 = pred(size)) then begin
      idx1:= ax1 + size * ay1 -1; //порядкоый номер ячейки перед началом диапазона
      idx2:= ax2 + size * ay2; //порядкоый номер ячейки конца диапазона
      Result:= get_sum(idx2) - get_sum(idx1);
      exit;
  end;
  //если у нас столбец из не полных строк
  for i:= ay1 to ay2 do begin
     idx1:= ax1 + size * i -1; //порядкоый номер ячейки перед началом диапазона
     idx2:= ax2 + size * i; //порядкоый номер ячейки конца диапазона
     Inc(Result, get_sum(idx2) - get_sum(idx1));
  end;
 
end;
 
begin
  {$IFDEF DEBUG}
  Assign(Input, 'input.txt');
  Assign(Output, 'output.txt');
  reset(input);
  Rewrite(output);
  {$ENDIF}
  repeat
    Read(cmd);
    case cmd of
      0:
      begin
        Read(size);
      end;
 
      1:
      begin
        Read(a1, a2, a3);
 
        update(a1, a2, a3);
      end;
 
      2:
      begin
        Read(a1, a2, a3, a4);
 
        writeln(asum(a1, a2, a3, a4));
      end;
    end;
  until cmd = 3;
  {$IFDEF DEBUG}
  Close(Input);
  Close(Output);
  {$ENDIF}
end.
1
445 / 373 / 133
Регистрация: 09.09.2011
Сообщений: 1,343
01.04.2020, 17:36
блин, еле нашел, как там задачу отправить, мои опасения оправдались, часть тестов не проходят по времени

лимит там кстати 0,5 сек, и там где не проходит, всего на 1 десятую дольше работает. нужна какая-то небольшая оптимизация
Миниатюры
Мобильные телефоны  
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
01.04.2020, 17:36
Помогаю со студенческими работами здесь

Как убивают мобильные телефоны. Репортаж с лаборатории Nokia
Трудно представить, но есть люди, чья работа заключается в том, чтобы в буквальном смысле разбивать новые телефоны и подвергать их...

Как звонить с компьютера на мобильные телефоны(по России) бесплатно?
раньше с mail агента можно было...

Рэй Брэдбери не любит мобильные телефоны, Интернет и электронные книги
22 августа блистательному, неповторимому Рэю Брэдбери исполнится 90 лет. В прежние времена его называли бы пророком и проповедником, а...

БД телефоны
Спроектировать базу данных для регистрации телефонов (мобильных, домашних, служебных) студентов колледжа: определить отношения и их...

Тайваньские телефоны
Смотрел ролик про новый Айфон. Мужик долго его помоил. Потом достает другой айфон и говорит - Вот тайваньская копия ничем не уступит. Стало...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru