20230425-PAT甲级1169

题意:

先给出两个数字,之后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.";
    }
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值