题意:
先给出两个数字,之后n个人进行m轮游戏。
规则1:每个人按轮次给出一个数字,这个数字是前面提出过的所有有效数字中的某两个之差,否则会被淘汰。注意:淘汰时的数字以及该选手的后续数字不被计入。
规则2:该轮提出的数字前面没有被提过,否则会被淘汰。
思路:
除输入之外,需要被记录的都有哪些?
temp——记录都有哪些数字被提出过且有效。(方便flag数组的更新)
flag——该数字是否为前面提出过的数字之差。(判断当前选手提出的数字是否合理)
repeat——该数字是否在前面被提出过。(判断另外淘汰条件)
fh——该名选手是否被淘汰。(节省时间以及避免后续数字干扰)
numofrow——其实就是sizeof(fh)。(如果是0就可以break节省时间了)
关键代码:
两层循环内:
如果numofrow==0就可以break了(没有选手了)
如果fh[j]==0就continue跳过(选手淘汰了)
如果这个数字没出现过修改repeat记录一下,否则淘汰该选手。——规则2
如果这个数字不是前面某两个数的差值,淘汰该选手。——规则1
否则:用temp内每一个数字和这个数字做差值,将差值的flag改为1,证明这个差值出现过,同时将这个数字存入temp中。
回顾自己的代码真是又臭又长。。好多地方可以优化一下的尤其是tempp、temppp那里。。但是懒得改ヽ( ̄▽ ̄)ノ
测试点:
测试点3、4的问题是最初给的两个数字没有判断是否重复。
代码:
#include <bits/stdc++.h>
using namespace std;
int main(){
int num1, num2;
int n, m;//n行m列
cin >> num1 >> num2 >> n >> m;
vector<vector<int>> v(n, vector<int>(m, 0));
vector<int> temp;
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
cin >> v[i][j];
}
}
bool flag[100001] = {0};
bool repeat[100001] = {0};
temp.push_back(num1);
flag[num1] = 1;
temp.push_back(num2);
flag[num2] = 1;
temp.push_back(max(num1, num2) - min(num1, num2));
flag[max(num1, num2) - min(num1, num2)] = 1;
int numofrow = n, numoftemp = 3;
repeat[num1] = 1;
repeat[num2] = 1;
vector<bool> fh(n, 1);
for(int i=0; i<m; i++){
for(int j=0; j<n; j++){
if(numofrow == 0) break;
if(fh[j] == 0) continue;
else{
if(repeat[v[j][i]] == 0) repeat[v[j][i]] = 1;
else{
fh[j] = 0;
numofrow--;
cout << "Round #" << i+1 << ": " << j+1 << " is out." << endl;
continue;
}
if(!flag[v[j][i]]){
fh[j] = 0;
numofrow--;
cout << "Round #" << i+1 << ": " << j+1 << " is out." << endl;
}
else{
int tempp = numoftemp;
for(int k=0; k<tempp; k++){
int temppp = max(v[j][i], temp[k]) - min(v[j][i], temp[k]);
if(flag[temppp] == 0){
flag[temppp] = 1;
}
}
temp.push_back(v[j][i]);
numoftemp++;
}
}
}
if(numofrow == 0) break;
}
if(numofrow != 0){
cout << "Winner(s):";
for(int i=0; i<n; i++){
if(fh[i] == 1) cout << " " << i+1;
}
}
else{
cout << "No winner.";
}
}