A. Borya's Diagnosis
传送门:http://codeforces.com/contest/879/problem/A
本题是一个模拟问题。
依次访问n个元素,第i个元素首次出现于si时刻,之后相邻两次出现的时间间隔为di。求访问结束的时刻。
贪心地模拟之。
注意事项:当运算符“/”用于负操作数时,在C89中,其结果由实现定义;在C99中,除法的结果总是向零截取的!!
注意特判si>cur的情形,以避免“由实现定义”的负操作数除法“/”。
参考程序如下:
#include <stdio.h> #include <stdint.h> #define MAX_N 1000 int s[MAX_N], d[MAX_N]; int main(void) { int n; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d%d", &s[i], &d[i]); int cur = 0; for (int i = 0; i < n; i++) { if (s[i] > cur) cur = s[i]; else { int j = (cur - s[i]) / d[i]; cur = s[i] + d[i] * (j + 1); } } printf("%d ", cur); return 0; }
B. Table Tennis
传送门:http://codeforces.com/contest/879/problem/B
本题是一个模拟问题。
n个人排成队列进行比赛,比赛规则如下:
①队首的两个人比赛,胜出者留在队首,另一个人去队尾;
②当一个人总共胜出k次时,比赛结束,这个人成为最终的赢家;
③两个人比赛时,能量值较大的人胜出。
对于最初的队列,第i个人的能量值为ai。已知a[1..n]是1..n的一个排列。
求最终赢家的能量值。
贪心地模拟之。
若k≥n,则所求结果是全局最优解,即最大的能量值max{ai|1≤i≤n}。
若k<n,则直接用队列模拟即可,注意设置计数器cnt,表示队首胜利的次数。
参考程序如下:
#include <bits/stdc++.h> using namespace std; queue<int> q; int main(void) { int n; int64_t k; scanf("%d%I64d", &n, &k); for (int i = 0; i < n; i++) { int a; scanf("%d", &a); q.push(a); } if (k >= n) { int ans = 0; while (!q.empty()) { if (q.front() > ans) ans = q.front(); q.pop(); } printf("%d ", ans); return 0; } int cur = q.front(); q.pop(); int cnt = 0; while (cnt < k) { int fnt = q.front(); if (cur > fnt) { cnt++; q.pop(); q.push(fnt); } else { cnt = 1; q.pop(); q.push(cur); cur = fnt; } } printf("%d ", cur); return 0; }