Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
HarleyDavids0n
0 / 0 / 1
Регистрация: 03.11.2015
Сообщений: 23
1

Моделирование распространения эпидемии

04.12.2015, 14:51. Просмотров 329. Ответов 0
Метки нет (Все метки)

Вводим размеры поля
Например:
4 4
Потом заполняем его с клавиатуры ([o] - здоровые клетки, [.] - пустота, [!] - больная клетка):
Например:
o.oo
o.oo
o..o
!o.o
И тут самое интересное, программа должна рассчитать сколько здоровых клеток заразит больная клетка, и сколько затрачено дней.
За один день заражаются клетки около восклицательного знака (сверху и снизу, слева и справа):
то есть:
Было:
o.oo
o.oo
o..o
!o.o
Первый день (не выводится):
o.oo
o.oo
!..o
!!.o
Второй день (не выводится):
o.oo
!.oo
!..o
!!.o
Третий день (не выводится):
!.oo
!.oo
!..o
!!.o
В итоге программа выведет:
Зараженных 5, количеств дней 3.

Еще пример работы программы:

Размеры поля:
4 4
oooo
o.oo
o..o
!o.o
Зараженных: 12, количество дней: 9

Размеры поля:
2 2
.o
o.
Никто не заражен.

Размеры поля:
4 4
oooo
oooo
oooo
Xooo
Неверный ввод.

Размеры поля:
4 4
oooo
ooooo
oooo
!ooo
Неверный ввод.

Размеры поля:
5 4
oooo
oooo
oooo
!ooo
Неверный ввод.

Размеры поля:
7 8
!ooooooo
.......o
oooooooo
o.......
oooooooo
.......o
oooooooo
Зараженных: 35, Количество дней: 34

Размеры поля:
4 4
oooo
oooo
oooo
!ooo
Зараженных: 16, Количество дней: 6

За неверный ввод воспринимается:
Размеры поля не целое число
При вводе элементов поля не использован отступ (Enter)
Поле не соответствует введенным размерам
Использованы символы кроме ! . o

Необходимы советы начинающему программисту от профессионалов. Спасибо!

Добавлено через 13 часов 24 минуты
Помощь с другого ресурса, программа выводит, все правильно, однако считает только зараженные клетки, не учитывает первоначальные восклицательные знаки:
так же посоветовал мне:
там нужно на этапе заполнения посчитать сколько зараженных было добавлено и потом прибавить к infected_n
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
//
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
#define CELL_HEALTHY 'o'
#define CELL_VOID '.'
#define CELL_SICK '!'
#define CELL_ALMOST_SICK 'X'
 
#define ASK_FOR_FIELD_SIZE_PROMPT "Field size: "
#define ASK_FOR_FIELD_FILL_PROMPT "Now fill it:\n"
 
#define FIELD_MAX_W 100
#define FIELD_MAX_H 100
 
#define RESULT_OK 0
#define ERROR_FIELD_SIZE_INVALID 1
#define ERROR_FIELD_INVALID_CELL_VALUE 2
#define ERROR_FIELD_INVALID_CELL_COUNT 3
 
#define epic_fail( r ) { printf("Error: %s\n", error_names[r]); exit(1); }
#define invalid_cell( cell ) ((cell != CELL_HEALTHY && cell != CELL_VOID && cell != CELL_SICK) ? 1 : 0)
#define isspace( c ) (c=='\r' || c=='\n' || c==' ')
#define infect( x, y ) if ( field[y][x] == CELL_HEALTHY ) field[y][x] = CELL_ALMOST_SICK
 
static const char * const error_names[] = {
    "RESULT_OK",
    "invalid field size",
    "invalid cell value",
    "invalid cells amount in a row",
};
 
int ask_for_field_size( int *w, int *h );
int ask_for_field_fill( char **field, int w, int h );
char **create_field( int w, int h );
char **clone_field( char **field, int w, int h );
void do_the_math( char **field, int w, int h, int *days, int *infected_n );
void debug_field( char **field, int w, int h );
void plz_no_errors( int r );
char *trim( char *str );
 
int main(void) {
    int field_w, field_h; // размеры поля
    char **field; // поле
    int days, infected_n; // как быстро и сколько заразит
 
    // вводим размеры поля:
    plz_no_errors(ask_for_field_size(&field_w, &field_h));
 
    // создаем 2D массив:
    field = create_field(field_w, field_h);
 
    // заполняем поле:
    plz_no_errors(ask_for_field_fill(field, field_w, field_h));
 
debug_field(field, field_w, field_h);
 
    printf("Now we will count ... ");
 
    // посчитать сколько заразит и как быстро
    do_the_math(field, field_w, field_h, &days, &infected_n);
 
    printf("DONE\ninfected: %d, days: %d\n", infected_n, days);
 
debug_field(field, field_w, field_h);
 
    //free_field(field, field_w, field_h);
}
 
char **clone_field( char **field, int w, int h ) {
    int x, y;
 
    char **clone = (char **)malloc(h * sizeof(char *));
 
    for ( y=0; y<h; y++ ) {
        clone[y] = (char *)malloc(w * sizeof(char));
 
        for ( x=0; x<w; ++x ) {
            clone[y][x] = field[y][x];
        }
    }
 
    return clone;
}
 
void do_the_math( char **field, int w, int h, int *days, int *infected_n ) {
    int x, y;
    int infected_today;
 
    *days = 0;
    *infected_n = 0;
 
    //char **clone = clone_field(field, w, h);
 
    while ( 1 ) {
        infected_today = 0;
 
        for ( y=0; y<h; y++ ) {
            for ( x=0; x<w; ++x ) {
                if ( field[y][x] == CELL_SICK ) {
                    // top (y-1, x)
                    if ( y-1 >= 0 ) { // exists
                        infect(x, y-1);
                    }
                    // bottom (y+1, x)
                    if ( y+1 < h ) { // exists
                        infect(x, y+1);
                    }
                    // left (y, x-1)
                    if ( x-1 >= 0 ) { // exists
                        infect(x-1, y);
                    }
                    // right (y, x+1)
                    if ( x+1 < w ) { // exists
                        infect(x+1, y);
                    }
                }
            }
        }
 
        // convert CELL_ALMOST_SICK to CELL_SICK and increment infected_n
 
        for ( y=0; y<h; y++ ) {
            for ( x=0; x<w; ++x ) {
                if ( field[y][x] == CELL_ALMOST_SICK ) {
                    field[y][x] = CELL_SICK;
                    infected_today++;
                }
            }
        }
 
        if ( !infected_today ) break;
 
        *infected_n += infected_today;
        (*days)++;
    }
 
    //free_field(clone, w, h);
}
 
int ask_for_field_fill( char **field, int w, int h ) {
    printf(ASK_FOR_FIELD_FILL_PROMPT);
 
    char str[FIELD_MAX_W + 1]; // read buffer
    char *str_trimmed;
    int str_len;
    int x, y;
 
    // сначала заполняем первый ряд, потом второй и т.п.
    for ( y=0; y<h; y++ ) {
        while ( 1 ) {
            memset(str, 0, FIELD_MAX_W + 1);
            fgets(str, FIELD_MAX_W, stdin);
            str_trimmed = trim(str);
            str_len = strlen(str_trimmed);
 
            if ( !str_len ) {
                continue; // пропускаем пустые линии
            }
 
            if ( str_len != w ) {
                return ERROR_FIELD_INVALID_CELL_COUNT; // у нас ячеек больше или меньше, чем ввели буковок
            }
 
            // наконец-то заполняем
            for ( x=0; x<w; ++x ) {
                if ( invalid_cell(str_trimmed[x]) ) {
                    return ERROR_FIELD_INVALID_CELL_VALUE; // какую-то херню ввели
                }
 
                field[y][x] = str_trimmed[x];
            }
            break;
        }
    }
 
    return RESULT_OK;
}
 
char **create_field( int w, int h ) {
    int x, y;
 
    char **field = (char **)malloc(h * sizeof(char *));
 
    for ( y=0; y<h; y++ ) {
        field[y] = (char *)malloc(w * sizeof(char));
    }
 
    return field;
}
 
void debug_field( char **field, int w, int h ) {
    int x, y;
 
    for ( y=0; y<h; y++ ) {
        for ( x=0; x<w; ++x ) {
            printf("%c ", field[y][x]);
        }
        printf("\n");
    }
}
 
int ask_for_field_size( int *w, int *h ) {
    printf(ASK_FOR_FIELD_SIZE_PROMPT);
 
    *w = 0;
    *h = 0;
 
    scanf("%d %d", w, h);
 
    if ( *w < 1 || *w > FIELD_MAX_W || *h < 1 || *h > FIELD_MAX_H ) {
        return ERROR_FIELD_SIZE_INVALID;
    } else {
        return RESULT_OK;
    }
}
 
void plz_no_errors( int r ) {
    if ( r != RESULT_OK ) {
        epic_fail(r);
    }
}
 
char *trim( char *str ) {
    char *end;
 
    while ( isspace(*str) ) str++;
 
    if ( *str == 0 ) {
        return str;
    }
 
    end = str + strlen(str) - 1;
 
    while ( end > str && isspace(*end) ) {
        end--;
    }
 
    *(end+1) = 0;
 
    return str;
}
И еще помощь от эксперта:
Это ж алгоритм открытия пустой области - по примеру игры "Сапер". Сам лично не видел его - но попробую логически сформулировать. Нам нужно два стека - которые мы будем постоянно swap-ать, удобно сделать массив из двух стеков. В первый мы будем ложить уже зараженные клетки, во второй клетки которые будут заражены на следующий день. Допустим отталкиваясь от вашего примера - уже имеем одну зараженную клетку. Число возможных зараженных клеток за один день = 4.Проверка по алгоритму.
1.Если верхняя/нижняя/левая/правая клетка относительно зараженной лежит в области границ массива и это здоровая клетка заталкиваем его в стек заражения след. днем. Иначе не заталкиваем. Нашу зараженную клетку относительно который мы проверяли выталкиваем из стека.
2.Повторяем эту проверку до тех пор пока не вытолкнем все зараженные клетки. Таким образом мы заполним второй стек, и поменяем местами стеки в след итерации цикла, чтобы заполнять по алгоритму уже пустой стек, а этот наоборот станет зараженным. Все это повторяем пока оба стека не окажутся пустыми.
Форматирование ячеек думаю сами сделаете...


Попробую, выполнить
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.12.2015, 14:51
Ответы с готовыми решениями:

Моделирование распространения эпидемии
Питаюсь запустить пример модели распространения эпидемии из книги Кудрявцева. После трансляции в...

Моделирование процессов распространения электромагнитных волн
Очень нужна помощь, используя уравнение Гельмгольца, реализовать нужно либо на C# либо на Delphi:...

Модель эпидемии.
Построить и исследовать модель эпидемии в городе с 300 тыс. жителей с фиксированным инкубационным...

Процесс развития эпидемии
Выявление основных особенностей. Процесс развития эпидемии представим в виде двух дифференциальных...

Нет ли сейчас эпидемии приводящей к BSOD 0A?
Мне в последние дни позвонило несколько знакомых, у которых на компе выскакивает BSOD...

0
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.12.2015, 14:51

Новый Facebook вирус приобрел масштабы эпидемии
Обнаруженный сегодня в крупнейшей соцсети фишинговый вирус продолжает бесконтрольное...

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

Из 200 сотрудников данного предприятия в разгар эпидемии заболеют ровно 60 челове
Добрый вечер. Имеется такая задача: В разгар эпидемии вероятность заболеть для каждого сотрудника...


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

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

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