10903. Турнир гора – бумага - ножницы
Игра гора – ножницы - бумага
ведется двумя игроками A и B. Каждый из игроков независимо друг от друга
выбирает гору, ножницы или бумагу. Бумага выигрывает у горы, ножницы выигрывают
у бумаги, гора выигрывает у ножниц.
Проводится турнир среди n
игроков, в котором каждый участник играет с каждым по k игр. Итого проводится k
* n * (n – 1) / 2 игр. Для каждого игрока следует найти средний выигрыш.
Он равен w / (w + l), где w – число выигранных игр, l – число проигранных.
Вход.
Первая строка каждого теста содержит количество игроков n (1 £ n
£ 100) и количество проведенных каждым участником игр k (1 £ k £ 100). Далее следуют игры, каждая
их которых имеет формат p1,
m1, p2, m2
(1 £ p1, p2 £ n). Здесь p1, p2
– номера игроков, m1, m2 – их выбор. Последняя
строка содержит единственный ноль и не обрабатывается.
Выход. Для каждого игрока в каждом тесте
вывести его средний выигрыш с тремя точками после запятой. Если средний выигрыш
неопределен, то вывести ‘-‘. Выходные данные тестов разделять пустой строкой.
2 4
1 rock 2 paper
1 scissors 2 paper
1 rock 2 rock
2 rock 1 scissors
2 1
1 rock 2 paper
0
Пример выхода
0.333
0.667
0.000
1.000
моделирование
Для каждого теста следует
промоделировать игру, запоминая количество выигрышей и проигрышей каждого
игрока. Далее для каждого игрока вывести значение w / (w + l), где w – число его выигранных игр, l
– число проигранных. Если для некоторого игрока значение w + l равно 0, то выводим
‘-‘.
В первом примере проведено 4
игры, три из которых результативны (не являются ничьими). Первый игрок выиграл
1 раз, проиграл 2 раза. Средний выигрыш первого игрока составляет 1 / (1 + 2) =
0.333.
В символьные массивы m1 и m2
считываем исходы текущей игры: гора, ножницы или бумага. players[i][1] содержит число выигранных игр i – ым игроком, а players[i][0] – число проигранных.
char m1[10], m2[10];
int players[MAX][2];
Функция wins возвращает -1, если
текущая игра заканчивается ничьей. Ничья возможна лишь в том случае, когда оба
игрока выбрали одинаковый исход. Функция wins возвращает 1, если исход,
находящийся в m1, побеждает исход, находящийся в m2. Иначе возвращается 0.
Проверку исхода можно совершать,
не сравнивая его целиком со словом, а лишь проверяя его первую букву. Например,
массив m1 содержит исход «rock» тогда и только тогда, когда m1[0] = ‘r’.
int wins(void)
{
if (((m1[0]
== 'p') && (m2[0] == 'p')) ||
((m1[0] == 'r')
&& (m2[0] == 'r')) ||
((m1[0] == 's')
&& (m2[0] == 's'))) return -1;
if (((m1[0]
== 'p') && (m2[0] == 'r')) ||
((m1[0] == 'r')
&& (m2[0] == 's')) ||
((m1[0] == 's')
&& (m2[0] == 'p'))) return 1;
return 0;
}
Основной цикл программы. Читаем
входные значения n, k. Обнуляем массив players – изначально
каждый игрок имеет 0 выигрышей и 0 проигрышей.
scanf("%d %d",&n,&k);
do{
memset(players,0,sizeof(players));
Читаем данные k*n*(n – 1)/2 игр. Увеличиваем на единицу
players[i][1], если в игре побеждает i - ый игрок, и players[i][1], если i - ый игрок проигрывает.
for(i = 0; i
< k*n*(n-1)/2; i++)
{
scanf("%d
%s %d %s\n",&p1,m1,&p2,m2);
if ((res =
wins()) == -1) continue;
if (res)
{players[p1][1]++; players[p2][0]++;}
else
{players[p2][1]++; players[p1][0]++;}
}
Выводим средний выигрыш для
каждого игрока. Если игрок не имеет выигрышей и проигрышей (а имеет только
ничьи), то его средний выигрыш определить невозможно, в таком случае выводим
‘-‘.
for(i = 1; i
<= n; i++)
if
(!(players[i][0] + players[i][1])) printf("-\n");
else
printf("%.3lf\n",1.0*players[i][1]
/ (players[i][0] + players[i][1]));
Между тестами следует выводить
пустую строку. После вывода результатов на последний тест печатать пустую строку
не следует.
scanf("%d
%d",&n,&k);
if (n)
printf("\n");
} while(n);