水面上有若干石頭,初始位置不同。石頭被扔出後,每次跳躍間隔固定距離 dd,直到超出邊界。每次跳躍計為一次「跳」。給定所有石頭的初始位置 pos、跳躍間隔 dd,求:
num 最大)last 最大者優先pos 最大者優先dd 最大者優先輸出獲勝石頭的參數。
數據範圍較小(石頭數 ≤ 100,位置 ≤ 10000),直接模擬每顆石頭的跳躍過程:
struct Stone {
int pos; // 初始位置
int dd; // 跳躍間隔
int num; // 跳躍次數
int last; // 最後位置
};
int simulate(Stone &s, int boundary) {
s.num = 0;
s.last = s.pos;
int cur = s.pos;
while (true) {
cur += s.dd;
if (cur > boundary) break; // 超出邊界停止
s.num++;
s.last = cur;
}
return s.num;
}
bool cmp(const Stone &a, const Stone &b) {
if (a.num != b.num) return a.num > b.num; // 次數優先
if (a.last != b.last) return a.last > b.last; // 最後位置優先
if (a.pos != b.pos) return a.pos > b.pos; // 初始位置優先
return a.dd > b.dd; // 間隔優先
}
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
struct Stone {
int pos, dd, num, last;
};
int main() {
int n, boundary;
while (scanf("%d%d", &n, &boundary) == 2) {
vector stones(n);
for (int i = 0; i < n; i++) {
scanf("%d%d", &stones[i].pos, &stones[i].dd);
}
for (auto &s : stones) {
s.num = 0;
s.last = s.pos;
int cur = s.pos;
while (true) {
cur += s.dd;
if (cur > boundary) break;
s.num++;
s.last = cur;
}
}
sort(stones.begin(), stones.end(), [](const Stone &a, const Stone &b) {
if (a.num != b.num) return a.num > b.num;
if (a.last != b.last) return a.last > b.last;
if (a.pos != b.pos) return a.pos > b.pos;
return a.dd > b.dd;
});
printf("%d %d %d %d\n",
stones[0].pos, stones[0].dd, stones[0].num, stones[0].last);
}
return 0;
}
O(boundary / dd),最壞 O(boundary)O(n × boundary),n≤100, boundary≤10000 即 10^6 量級,極快O(n log n) 可忽略num=0, last=posdd=0:無限循環,題目保證 dd>0 或需特判while(scanf(...)==2) 循環讀入