Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/34: Рейтинг темы: голосов - 34, средняя оценка - 4.56
3 / 3 / 0
Регистрация: 12.01.2014
Сообщений: 36

Разбор олимпиадной задачи прошлого года

27.01.2014, 14:40. Показов 7087. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!..
В прошлом году на региональном этапе всероссийской олимпиады школьников по информатике была задача A + B = C
Условие задачи:
Кликните здесь для просмотра всего текста
#111490 A + B = C
Темы: [Динамическое программирование] [Динамическое программирование: последовательности]
Источники: [ Личные олимпиады, Всероссийская олимпиада школьников, Региональный этап, 2013, 1 день, Задача C ]
ограничение по времени на тест 2.0 second; ограничение по памяти на тест 64 megabytes
Часто для пробного тура на различных олимпиадах по информатике предлагается задача «A + B», в которой по заданным целым числам A и B требуется найти их сумму.

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

Пусть председатель жюри выбрал число C, запись которого состоит из n десятичных цифр и не начинается с нуля. Теперь он хочет подобрать такие целые положительные числа A и B, чтобы их сумма была равна C, и запись каждого из них также состояла из n десятичных цифр и не начиналась с нуля. В дополнение к этому председатель жюри старается подобрать такие числа A и B, чтобы каждое из них было красивым. Красивым в его понимании является число, запись которого не содержит двух одинаковых подряд идущих цифр. Например, число 1272 считается красивым, а число 1227 — нет.

Требуется написать программу, которая для заданного натурального числа C вычисляет количество пар красивых положительных чисел A и B, сумма которых равна C. Поскольку количество пар красивых чисел может быть большим, необходимо вывести остаток от деления этого количества на число 109+7.

Входные данные
Входной файл содержит одно целое положительное число C. Число C не начинается с нуля. Количество цифр в записи числа С не превышает 100 000 .

Выходные данные
Выходной файл должен содержать одно целое число — остаток от деления количества искомых пар красивых чисел A и B на число 109+7.

Система оценивания
Правильные решения для тестов, в которых 1 ≤ C ≤ 999 (1 ≤ n ≤ 3), будут оцениваться из 25 баллов.

Правильные решения для тестов, в которых 1 ≤ C ≤ 999 999 (1 ≤ n ≤ 6), будут оцениваться из 50 баллов.

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

Пояснения к тестам

Число 22 можно представить в виде суммы двузначных чисел тремя способами: 10 + 12, 11 + 11, 12 + 10. Способ 11 + 11 не подходит, поскольку число 11 не является красивым. Следовательно, ответ для числа 22 равен 2.

Число 200 можно представить в виде суммы трехзначных чисел единственным способом: 100 + 100. Этот способ не подходит, поэтому ответ для числа 200 равен 0.

Число 1000 нельзя представить в виде суммы четырехзначных чисел, поэтому ответ для числа 1000 аналогично равен 0.

Примеры
входные данные
22
выходные данные
2
входные данные
200
выходные данные
0
входные данные
1000
выходные данные
0
входные данные
239
выходные данные
16


Решение:
Кликните здесь для просмотра всего текста
Задача 3. «A+B=C»
Для решения данной задачи можно применить метод динамического программирования [20]. С этой целью введем следующие обозначения.
Обозначим через C’ число, состоящее из последних k цифр числа С.
Пусть s[k][i][j][0] – это количество способов разложения числа С’ в сумму чисел А’ и B’, каждое из которых состоит из k цифр, при этом A’ начинается с цифры i (0 ≤ i ≤ 9), а B’ – с цифры j (0 ≤ j ≤ 9). Рассматриваются также суммы, в которых слагаемые начинаются с нуля, например, 25 = 03 + 22.
Далее припишем слева к числу C’ единицу и обозначим через s[k][i][j][1] количество способов разложения нового числа в такую же сумму, о которой шла речь выше (можно сказать, что здесь при сложении «переносится 1 в старший разряд»). Обобщая вышесказанное, s[k][i][j][p] – это количество способов представления числа C’ в виде суммы с переносом p в старший разряд (0 ≤ i ≤ 10, 0 ≤ j ≤ 10, 0 ≤ p ≤ 1, 1 ≤ k ≤ |C| и
|C| обозначает длину исходного числа – n).
С учетом сказанного не сложно придти к выводу, что ответ на поставленную задачу будет равен сумме всех s[|C|][i][j][0] по всем i и j, отличным от нуля (слагаемые по условию не могут начинаться с нуля). Теперь осталось только вычислить s[k][i][j][p]. Покажем, как это можно сделать.
Пусть t – k-я справа цифра числа C. Рассмотрим три случая.
1) (i + j) = (10p + t), то есть, (i + j) равно либо t, либо (10 + t) в зависимости от значения p. В этом случае переноса вправо не происходит, и нужно только просуммировать s[k – 1][x][y][0] для всех 0 ≤ x ≤ 9 и 0 ≤ y ≤ 9 кроме тех, для которых i = x или j = y , то есть, две соседние цифры равны.
2) (i + j) = (10p + t – 1). В этом случае 1 переносится в правый разряд, и теперь нужно просуммировать s[k – 1][x][y][1] (опять же кроме тех, для которых i = x или j = y).
3) В остальных случаях s[k – 1][x][y][1] = 0, так как нельзя получить цифру t из чисел, начинающихся на i и j.
Алгоритм, реализующий описанное решение, имеет линейную сложность относительно длины числа С, но константа будет довольно большой: для каждой длины числа k необходимо вычислить 10 ∙ 10 ∙ 2 = 200 чисел s[k][i][j][p], а для вычисления каждого из них требуется порядка 10 ∙ 10 = 100 сложений. Но на самом деле большинство значений s[k][i][j][p] будет равно нулю (см. третий случай, о котором речь шла выше), и всего потребуется вычислить лишь порядка 40 ненулевых таких значений. В итоге, асимптотическая сложность алгоритма будет порядка 4000N.
Заметим, что искомое количество пар красивых чисел A и B может быть очень большим, поэтому ответ в задаче предлагается выводить по модулю (109+7). Все вычисления также нужно делать по этому модулю, чтобы в процессе вычислений не произошло переполнение используемого типа.


Первые возникшие вопросы:
Почему именно такая организация массива: s[k][i][j][p] ?
Не совсем понятно что означает индекс p..
Помогите, пожалуйста, разобраться в решение задачи.. И в том, как можно реализовать это решение на c#..
Такое ощущение, что в объяснение решения задачи пропущен какой то важный логический момент...
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.01.2014, 14:40
Ответы с готовыми решениями:

Как рассчитать темп инфляции, если известен индекс цен прошлого года и текущего года
Рассчитать темп инфляции, если известен индекс цен прошлого года и текущего года т=((ид.т.г-ид.п.г)/ид.т.г)*100 как это записать в...

Решение олимпиадной задачи (ч.2)
i:= 1 j:= 257 Цикл i:= i + x; j:= j - x; x:= x - 1 выполнили 25 раз и стало i= j. Надо найти х.

Решение олимпиадной задачи
Доброй ночи! У меня возникла проблема с онлайн проверкой задачи. ссылка на условие мое решение: #include <iostream> ...

17
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
28.01.2014, 17:03
Цитата Сообщение от Drakon5999 Посмотреть сообщение
Не совсем понятно что означает индекс p..
Для чего p понятно число с может содержать до 1000000 знаков и чтобы работать с ним придется работать с массивами сложим число a = 237 c числом b 135

C#
1
2
3
a[0] =2 b[0] =1   // тут  не нужен перенос разряда т.е.  p = 0
a[1] =3 b[1] =3   // тут  не нужен перенос разряда т.е.  p = 0
a[2] =7 b[2] =5   // тут  нужен перенос разряда т.е.  p = 1   ,  т.е. a[1] + b[1]+ p
Добавлено через 10 минут
Число 22 можно представить в виде суммы двузначных чисел тремя способами: 10 + 12, 11 + 11, 12 + 10. Способ 11 + 11 не подходит, поскольку число 11 не является красивым. Следовательно, ответ для числа 22 равен 2.

C#
1
s[k][i][j][0]
C#
1
2
3
s[0][1][1][0]
s[1][0][2][0]
// 10 +12 = 22
C#
1
2
3
s[0][1][1][0]
s[1][1][1][0]
// 11 +11 = 22
Добавлено через 42 минуты
Я уже подзабыл математику , но алгоритм будет примерно такой , если ошибаюсь поправите

C#
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
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
 
            string c = "239";
 
            int[, , ,] s = new int[c.Length, 9, 9, 9];
            int p = 0;
 
            // начинаем выбирать все числа  сумма которых равна С
 
            for (int k = c.Length-1; k <= 0; k--) 
            {
                for (int i = 0;  i<= 9; i++)
                {
                    for (int j = 0; j <= 9; j++)
                    {
 
                        if (j + i == c[k])
                        { 
                            // тут надо пока подумать
                        }
 
                    }
                }
            }
        
        }
    }
}
0
3 / 3 / 0
Регистрация: 12.01.2014
Сообщений: 36
28.01.2014, 17:10  [ТС]
Цитата Сообщение от EVG-1980 Посмотреть сообщение
[c.Length, 9, 9, 9]
Тут кажется будет 2...
0
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
28.01.2014, 17:17
Цитата Сообщение от Drakon5999 Посмотреть сообщение
Тут кажется будет 2...
289 - с[2] = 9 варианты 1+8 ; 2+7 ; 3+6 ; 4+5 ; 0+9

Добавлено через 4 минуты
тфу ты про Р да верно тут будет 2
0
3 / 3 / 0
Регистрация: 12.01.2014
Сообщений: 36
28.01.2014, 17:26  [ТС]
Цитата Сообщение от EVG-1980 Посмотреть сообщение
if (j + i == c[k])
c[k] нужно предварительно сконвертировать в число..
0
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
28.01.2014, 20:04
Drakon5999, сконвертируешь сам , я тебе накидал примерное решение , а не законченную программу

Добавлено через 47 минут
for (int k = c.Length-1; k <= 0; k--) кстати в этой строке тоже есть косяк

Добавлено через 1 час 11 минут
+ раз эта олимпиада по информатике (хотя мне кажется что данная задача больше подходит для олимпиады по математики)

победитель должен определятся примерно так

C#
1
2
sWatch.Start();
sWatch.Stop();
и выиграет тут чистый ASM
1
54 / 71 / 20
Регистрация: 26.06.2013
Сообщений: 194
28.01.2014, 20:19
C#
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
98
using System;
using System.Collections.Generic ;
using System.Linq;  
namespace ConsoleApplication8
{
    class zn
    {
        public int[] x = new int[10];
        public int[] y = new int[10];
        public int[] p = new int[10]; 
    }
    class Program
    {
        public static zn[] a;
        public static long[, , ,] b;
        static void sumwozwar(int x, int y,int num,int per )
        {  
                for (int i = 0; i < 10; i++)
                {
                    for (int j = 0; j < 10; j++)
                    {
                        if (x != i && y != j)
                        {
                            b[num, x, y, (x + y+per) / 10] += b[num + 1, i, j, per];
                        }
                    } 
                }
                b[num, x, y, (x + y + per) / 10] %= 1000000007;
        }//количество решений для одного из вариантов получение треб. цифры
        static void vozwar(int num, int k)
        { 
            for (int i = 0;i<10;i++)
            {
                int x, y;
                x = a[k].x[i];
                y = a[k].y[i];
                sumwozwar(x, y, num, 0);
            }
            k--;
            if (k < 0) k = 9; 
            for (int i = 0; i < 10; i++)
            {
                int x, y ;
                x = a[k].x[i];
                y = a[k].y[i]; 
                sumwozwar(x, y, num, 1);
            }
        }//возможные варианты
        static void w()
        {
            a = new zn[10];
            int[] z = new int[10];
            a = a.Select(e => new zn()).ToArray();
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    int sum = i + j;
                    int s1 = sum % 10;
                    int p = sum / 10;
                    a[s1].x[z[s1]] = i;
                    a[s1].y[z[s1]] = j;
                    a[s1].p[z[s1]] = p;
                    z[s1]++;
                }
            }
        } // получаем все возможные пары цифр сумма которых оканчивается требуемым числом 
        static void Main(string[] args)
        {
            w(); 
            string c = Console.ReadLine();
            b = new long[c.Length, 10, 10,2];
            int k = Convert.ToInt32(c[c.Length-1].ToString()); 
            for (int i=0;i<10;i++)
            { 
                    int x, y,p ;
                    x = a[k].x[i];
                    y = a[k].y[i];
                    p = a[k].p[i];
                    b[c.Length-1, x, y, p] = 1; 
            }
            for (int q=c.Length-2;q>-1;q--)
            { 
                    vozwar(q, k);
            }
            long sum = 0;
            for (int i=1;i<10;i++)
            {
                for (int j=1;j<10;j++)
                {
                    sum += b[0, i, j, 0];
                }
            }
            sum %= 1000000007;
            Console.WriteLine(sum);
        }
    }
}
1
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
28.01.2014, 20:30
Цитата Сообщение от dracon4ik Посмотреть сообщение
int k = Convert.ToInt32(c[c.Length-1].ToString());
Садись два
0
54 / 71 / 20
Регистрация: 26.06.2013
Сообщений: 194
28.01.2014, 20:36
EVG-1980, подскажите как правильно сделать? Все-таки я на C# перебрался недавно, причем с языка где используется не настолько строгая типизация.
0
3 / 3 / 0
Регистрация: 12.01.2014
Сообщений: 36
28.01.2014, 20:40  [ТС]
Цитата Сообщение от dracon4ik Посмотреть сообщение
причем с языка где используется не настолько строгая типизация.
Не по теме:
JS, PHP?
0
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
28.01.2014, 20:41
int k = (int)c[c.Length-1] - 48;
0
54 / 71 / 20
Регистрация: 26.06.2013
Сообщений: 194
28.01.2014, 20:49
Drakon5999,

Не по теме:

Python->VB.Net->C#



Добавлено через 3 минуты
Ну не знаю: прирост к скорости мизерный, но при поиске ошибок менее понятно что делает данный код.
0
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
28.01.2014, 21:04
////

Добавлено через 14 минут
У нас олимпиада
0
54 / 71 / 20
Регистрация: 26.06.2013
Сообщений: 194
28.01.2014, 21:28
На школьной главное не скорость, а на каком количестве тестов пройдет
0
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
29.01.2014, 07:03
Цитата Сообщение от dracon4ik Посмотреть сообщение
На школьной главное не скорость, а на каком количестве тестов пройдет
А тут поподробнее , что то я недопонимаю как рабочая программа может провалить тест?
0
3 / 3 / 0
Регистрация: 12.01.2014
Сообщений: 36
29.01.2014, 09:58  [ТС]
Цитата Сообщение от EVG-1980 Посмотреть сообщение
А тут поподробнее , что то я недопонимаю как рабочая программа может провалить тест?

1. Либо она не рассматривает все возможные варианты входных данных и выдает неверный ответ или ошибку выполнения при некоторых данных..
2. Либо она работает на некоторых тестах слишком долго или использует слишком много оперативной памяти и не укладывается в выделеные лимиты..
3. Либо она просто не работает как надо
0
Администратор
Эксперт .NET
 Аватар для tezaurismosis
9673 / 4825 / 763
Регистрация: 17.04.2012
Сообщений: 9,664
Записей в блоге: 14
29.01.2014, 14:17
Цитата Сообщение от EVG-1980 Посмотреть сообщение
int k = (int)c[c.Length-1] - 48;
Садись, три
C#
1
int k = c[c.Length-1] - 48;
1
192 / 199 / 82
Регистрация: 11.04.2013
Сообщений: 1,086
29.01.2014, 14:53
tezaurismosis,
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.01.2014, 14:53
Помогаю со студенческими работами здесь

Решение олимпиадной задачи
Есть задача, никак не могу решить не то что решить, но и до конца осознать условие. Буду рад любой помощи Ссылка удалена.

Решение олимпиадной задачи
Условие: Антон, Борис и Василий решили переплыть с одного берега озера на противоположный, расстояние между которыми составляет 3 км. При...

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

Показать в поле в запросе последнюю датой прошлого года
Здравствуйте! Возникла новая проблема и ни как не могу ее сделать. Суть такая: необходимо составить таблицу простоя оборудования. Если...

Найти файлы созданные в нечетные дни прошлого года
ребят подскажите как реализовать в bash коде следующее в каталог dir &lt;дата&gt; скопировать все файлы компьютера созданные в нечетные дни...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru