Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.89/18: Рейтинг темы: голосов - 18, средняя оценка - 4.89
1 / 1 / 0
Регистрация: 10.02.2010
Сообщений: 36
1

Вечный календарь

20.01.2016, 20:38. Показов 3776. Ответов 5
Метки нет (Все метки)

Привет, человеки.

Я тут решаю задачу, которая проверяется автоматической системой.

Вот задача:
Сейчас мы используем Григорианский календарь. В високосном году 366 дней, а в не високосном — 365. Год является високосным, если его номер кратен 400 либо кратен 4, но не кратен 100.
Например, 2004, 2080 и 2400 — високосные года. А 2001, 2081 и 1900 — не високосные.
Ваша задача написать программу, которая будет вычислять день недели, соответствующий заданной дате в ближайшем прошлом или в будущем, используя действующую систему исчисления лет.
Формат ввода

Входные данные содержат одно или несколько тестовых заданий. В каждой строке содержится по одному тестовому заданию. Каждая строка содержит день d, название месяца M и год y (1980 ≤ y ≤ 2100). Имя месяца записано на английском языке и начинается с заглавной буквы. Гарантируется, что дата корректная. Количество тестовых заданий не превышает 100 000.
Формат вывода

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

Пример:

Ввод:
1 January 2015
31 December 2015

Вывод:
Thursday
Thursday
Вот мое решение
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <iostream>
#include <fstream>
#include <string.h> 
 
using namespace std;
 
int main()
{
    ifstream input("input.txt");
    ofstream output("output.txt");
 
    int i = 0;
 
    while (!input.eof())
    {
        int day = 0;
        char monthName[20];
        int year = 0;
 
        input >> day >> monthName >> year;
 
        int month = 0;
        if (strcmp(monthName, "January") == 0)
        {
            month = 1;
        }
        else if (strcmp(monthName, "February") == 0)
        {
            month = 2;
        }
        else if (strcmp(monthName, "March") == 0)
        {
            month = 3;
        }
        else if (strcmp(monthName, "April") == 0)
        {
            month = 4;
        }
        else if (strcmp(monthName, "May") == 0)
        {
            month = 5;
        }
        else if (strcmp(monthName, "June") == 0)
        {
            month = 6;
        }
        else if (strcmp(monthName, "July") == 0)
        {
            month = 7;
        }
        else if (strcmp(monthName, "August") == 0)
        {
            month = 8;
        }
        else if (strcmp(monthName, "September") == 0)
        {
            month = 9;
        }
        else if (strcmp(monthName, "October") == 0)
        {
            month = 10;
        }
        else if (strcmp(monthName, "November") == 0)
        {
            month = 11;
        }
        else if (strcmp(monthName, "December") == 0)
        {
            month = 12;
        }
 
        int a = (14 - month) / 12;
        int y = year - a;
        int m = month + 12 * a - 2;
 
        int result = (7000 + (day + y + y / 4 - y / 100 + y / 400 + (31 * m) / 12)) % 7;
        char * dayName = "";
 
        switch (result)
        {
            case 0:
                dayName = "Sunday";
                break;
 
            case 1:
                dayName = "Monday";
                break;
 
            case 2:
                dayName = "Tuesday";
                break;
 
            case 3:
                dayName = "Wednesday";
                break;
 
            case 4:
                dayName = "Thursday";
                break;
 
            case 5:
                dayName = "Friday";
                break;
 
            case 6:
                dayName = "Saturday";
                break;
        }
 
 
        output << (i++ > 0 ? "\n\r" : "") << dayName;
    }
 
    output << "\0";
 
    input.close();
    output.close();
 
    return 0;
}
У меня, как вы могли догадаться, работает просто блестяще, выводит нужный день, в нужных количествах. Система же наглухо отказывается принимать мой ответ (уже и перевод каретки и добавил и нуль символ подсунул).

Собственно вопрос: что я делаю не так?

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

 Комментарий модератора 

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


{картинка с условием задачи удалена}
1

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.01.2016, 20:38
Ответы с готовыми решениями:

Вечный календарь
помогите сделать програму Вечный календарь,которая при введении любой даты может определить день...

Вечный календарь
Написал программу &quot;Вечный календарь&quot;, которая определяет день недели введенной даты и...

Вечный календарь ошибка компиляции
Здравствуйте!Написал программу при компиляции выдается ошибка.не могу разобраться где...

Вечный календарь: неразбериха с проверкой введения даты
Ребята, вот кусок моего кода. Работает, но есть проблема с февралём до 12 года - вводишь 30 или 31...

5
15109 / 8109 / 1958
Регистрация: 30.01.2014
Сообщений: 13,775
20.01.2016, 23:12 2
Fennec, я думаю, дело в том, что ты не делаешь перевод каретки после вывода дня недели так:
C++
1
output << dayName << '\n';
Попробуй сам не с файлами, а со стандартным вводом\выводом через консольку. Получится следующая вещь,
вводим
Bash
1
1 January 2015<enter>
программа выводит
Bash
1
Thursday
но перевод строки НЕ добавляет.
Значит следующую строку ты начнешь вводить сразу за `Thursday`. Однако в задании есть требование, что каждое испытание должно начинаться с новой строки. А в случае, если данные выводятся в файл, то будет лишняя пустая строка в ответах.
Кроме этого вижу не совсем корректную обработку завершения ввода, если данные вводить с консоли (выведет один лишний раз день недели, если пользователь нажал ctrl-z\ctrl-d).

Ну и конечно if`ы эти и switch вместо использования массивов не добавляют коду ни скорости, ни красоты.

А еще не очень понятно, как они различают варианты с вводом с консоли и варианты с вводом из файла. Там есть какой-то флаг при загрузке исходника?
0
1 / 1 / 0
Регистрация: 10.02.2010
Сообщений: 36
20.01.2016, 23:24  [ТС] 3
как они различают варианты с вводом с консоли и варианты с вводом из файла
не могу сказать, детали реализации системы проверки от меня скрыты )

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

насчет if'ов и switch'ей дельное замечание, вообще как-то из головы вылетело.
0
15109 / 8109 / 1958
Регистрация: 30.01.2014
Сообщений: 13,775
20.01.2016, 23:43 4
Лучший ответ Сообщение было отмечено Fennec как решение

Решение

Цитата Сообщение от Fennec Посмотреть сообщение
но я все же пользуюсь работой с файлами.
В этом случае получится пустая строка после каждого вывода.
Цитата Сообщение от Fennec Посмотреть сообщение
лишний перенос в конец
Нет, не добавит.
Будет только один лишний перенос в самом конце файла. Но эту ситуацию можно обработать. В остальных случаях переносы нужны именно после.
Цитата Сообщение от Fennec Посмотреть сообщение
не могу сказать, детали реализации системы проверки от меня скрыты
Возможно они используют по умолчанию ввод именно в консоль. А варианты с файлами запускают по принципу:
Bash
1
your_prog < input.txt > output.txt
В этом случае становится критично, чтобы программа работала с потоками ввода нормально.

Добавлено через 6 минут
В общем, примерно так:
Кликните здесь для просмотра всего текста

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
#include <iostream>
#include <fstream>
#include <cstring>
 
inline int select_month(char const * month)
{
    static char const * months[] =
    {
        "January", "February", "March", "April", "May", "June", "July"
      , "August", "September", "October", "November", "December"
    };
    for(size_t i = 0; i < 12; ++i)
    {
        // Сравниваем по 3 символа, этого вполне достаточно при заданных условиях
        if(std::strncmp(months[i], month, 3) == 0) 
        {
            return i + 1;
        }
    }
    return 0;
}
 
inline char const * select_day(size_t day)
{
    static char const * days[] =
    {
        "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
    };
    return days[day];
}
 
int main()
{
    std::istream & input  = std::cin; //("input.txt");
    std::ostream & output = std::cout; //("output.txt");
 
    int  day = 0;
    char monthName[20];
    int  year = 0;
    while((input >> day >> monthName >> year))
    {
        int month = select_month(monthName);
 
        int a = (14 - month) / 12;
        int y = year - a;
        int m = month + 12 * a - 2;
 
        int result = (7000 + (day + y + y / 4 - y / 100 + y / 400 + (31 * m) / 12)) % 7;
 
        output << select_day(result) << "\n"[input.eof()];
    }
    return 0;
}
1
1 / 1 / 0
Регистрация: 10.02.2010
Сообщений: 36
21.01.2016, 09:26  [ТС] 5
а что есть
C++
1
"\n"[input.eof()]
? мне как-то даже не сгуглилась такая конструкция
0
15109 / 8109 / 1958
Регистрация: 30.01.2014
Сообщений: 13,775
21.01.2016, 12:03 6
Цитата Сообщение от Fennec Посмотреть сообщение
"\n"[input.eof()]
eof() возвращает либо true, либо false. false неявно преобразуется в 0, true - в 1.
"\n" - это массив из 2х элементов. Элемент с индексом 0 - это символ переноса строки '\n', элемент с индексом 1 - символ конца строки '\0'.
Соответственно, пока eof() возвращает false, в поток уходит символ '\n', при true - символ конца строки '\0', который просто игнорируется текстовым потоком.

Вообще лучше так не делать без особой необходимости. Не смотря на то, что мы избавились от условного перехода, не факт что этот код в реальности будет быстрее работать на современных процессорах. Я просто писал код в браузере и мне было лень набирать еще один if.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.01.2016, 12:03

Вечный цикл
вы в вечном цикле выводите число и спрашиваете у пользователя больше меньше или равно ( = &gt; &lt; )....

Вечный цикл
является ли этот цикл зацикленным(вечным)? while(1){ for(i=8;i&lt;=190;i++){ ...

Непонятно почему вечный цикл
Собственно дело вот в чём, если в мейне ввести не цифру, а букву (cin&gt;&gt;k), то цикл резко ломается к...

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


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.