// 15 points
#include <bits/stdc++.h>
using namespace std;
int main() {
int m, n, s;
map<string, int> isTaken;
map<int, string> weibo;
cin >> m >> n >> s;
// 读取编号和昵称
for(int i = 1; i <= m; i++){
string str;
cin >> str;
weibo[i] = str;
isTaken[str] = false;
}
/*for(int i = 1; i <= m; i++){
cout << weibo[i] << " " << isTaken[weibo[i]] << endl;
}*/
if(weibo.size() < s) cout << "Keep going...";
else
for(auto wb = begin(weibo); wb != end(weibo); wb++){
// cout << wb.first << " " << ((wb.first - s) % n) << " " << wb.second << " " << isTaken[wb.second] << endl;
// 判断编号正确
if((wb->first - s) % n == 0){
// 并且是否已领
if(isTaken[wb->second] == false){
// 标记已领
isTaken[wb->second] = true;
cout << wb->second << endl;
}
// 该人已领顺次跳到下一位
else {
auto tmp = wb;
cout << (++tmp)->second << endl;
}
}
}
}
// AC
#include <bits/stdc++.h>
using namespace std;
int main() {
int m, n, s;
map<string, int> isTaken;
map<int, string> weibo;
cin >> m >> n >> s;
// 读取编号和昵称
for(int i = 1; i <= m; i++){
string str;
cin >> str;
weibo[i] = str;
isTaken[str] = false;
}
/*for(int i = 1; i <= m; i++){
cout << weibo[i] << " " << isTaken[weibo[i]] << endl;
}*/
int flag = false;
for(auto wb = begin(weibo); wb != end(weibo); wb++){
// cout << wb.first << " " << ((wb.first - s) % n) << " " << wb.second << " " << isTaken[wb.second] << endl;
// 判断编号正确
if(wb->first - s >= 0 && (wb->first - s) % n == 0){
// 并且是否已领
if(isTaken[wb->second] == false){
// 标记已领
isTaken[wb->second] = true;
cout << wb->second << endl;
}
// 该人已领顺次跳到下一位
else s++;
flag = true;
}
}
if(flag == false) cout << "Keep going...";
}
if(weibo.size() < s) cout << "Keep going...";
当时判断没有中奖的方法,是判断第一个中奖序号是否大于元素的个数。但是测试3有一个问题,如果转发数为 0 并且第一个序号为 0 的时候,这样判断会没有输出。
if(flag == false) cout << "Keep going...";
所以得改成是否有输出的判断。
同时测试点3当时没有理解题目这个意思 “当前中奖位置的网友已经中过奖,则跳过他顺次取下一位” 以为仅仅只是取当前中奖的下一个,后面的判断依旧以这个中奖过的人开始,间隔 N 个人。
但是看了别人众多代码,发现要改变 s++ 指向下一个人,以中奖的为新的开始序号,再间隔 N 个人。
else s++;
不过题目说的是 “从转发的网友中按顺序每隔 N 个人就发出一个红包” 并没明确说明会以 “中奖” 为开始计算N个人。样例也没有指明这点。这种问题,考试时候很难看出有这个测试点。
原文:https://www.cnblogs.com/Atl212/p/15265465.html