#P1500. 第3题-小红训练
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 114
            Accepted: 47
            Difficulty: 5
            
          
          
          
                       所属公司 : 
                              京东
                                
            
                        
              时间 :2023年8月26日
                              
                      
          
 
- 
                        算法标签>模拟          
 
第3题-小红训练
思路:模拟
按照题意进行模拟题目中描述的所有情况即可
时间复杂度:O(n)
###cpp
#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n, m;
    cin >> n >> m;
    // 0 为红,1为蓝
    vector<int> RB(n);
    // h 为战斗力
    vector<int> h(n);
    string s;
    for (int i = 0; i < n; ++i) {
        cin >> s >> h[i];
        if (s == "R") RB[i] = 0;
        else RB[i] = 1;
    }
    // 表示之前的战斗中第 i 个人是否已经失败过
    vector<int> lose(n);
    int x, y;
    string c1, c2;
    for (int i = 0; i < m; ++i) {
        cin >> x >> y >> c1 >> c2;
        x--, y--;
        if (lose[x] || lose[y]) continue;
        // 都不公开身份
        if (c1 == "N" && c2 == "N") continue;
        // 两者是同一队伍的
        if (RB[x] == RB[y]) continue;
        // 如果红色方知道对面是红色方,则直接战斗
        if ((RB[x] == 0 && c2 == "Y") || (RB[y] == 0 && c1 == "Y")) {
            if (h[x] == h[y]) lose[x] = lose[y] = 1;
            else if (h[x] > h[y]) lose[y] = 1;
            else lose[x] = 1;
            continue;
        }
        // 如果红色方不知道,但是蓝色方知道对手的战斗力,低于其战斗力,则战斗
        if (RB[x] == 1 && c2 == "Y") {
            if (h[x] > h[y]) lose[y] = 1;
            continue;
        }
        if (RB[y] == 1 && c1 == "Y") {
            if (h[y] > h[x]) lose[x] = 1;
            continue;
        }
    }
    for (int i = 0; i < n; ++i)
        if (lose[i]) cout << 'L';
        else cout << 'W';
    cout << "\n";
    return 0;
}
python
import sys 
input = lambda: sys.stdin.readline().strip()
write = lambda x: sys.stdout.write(str(x)+ '\n')
def attack(x, y, player, record):
    # 跳过
    if (record[x] == 'L' or record[y] == 'L'):
        return
    if player[x][1] == player[y][1]:
        record[x] = 'L'
        record[y] = 'L'
        return
    if player[x][1] > player[y][1]:
        record[x] = 'W'
        record[y] = 'L'
        return
    if player[x][1] < player[y][1]:
        record[x] = 'L'
        record[y] = 'W'
        return
n, m = map(int, input().split())
player = []
for i in range(n):
    temp = list(input().split())
    temp[1] = int(temp[1])
    player.append(temp)
record = ['W'] * n
for i in range(m):
    x, y, c1, c2 = map(str, list(input().split()))
    x = int(x)-1
    y = int(y)-1
    # 如果红队选手知道了本轮战斗的对手是蓝队选手,那么红队选手会直接攻击对方
    if player[x][0] == 'R':
        if (c2 == 'Y' and player[y][0] == 'B'):
            attack(x, y, player, record)
            continue
    if player[y][0] == 'R':
        if (c1 == 'Y' and player[x][0] == 'B'):
            attack(x, y, player, record)
            continue
    # 如果蓝队选手知道了本来战斗的对手是红队选手,那么只有蓝队选手的战斗力高于对手时,他才会攻击对方
    if player[x][0] == 'B':
        if (c2 == 'Y' and player[y][0] == 'R' and player[y][1] < player[x][1]):
            attack(x, y, player, record)
            continue
    if player[y][0] == 'B':
        if (c1 == 'Y' and player[x][0] == 'R' and player[x][1] < player[y][1]):
            attack(x, y, player, record)
            continue
res = ''.join(map(str, record))
write(res)
java
import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) throws InterruptedException {
        Scanner sc=new Scanner(System.in);
        String[] in=sc.nextLine().split(" ");
        int n=Integer.parseInt(in[0]);
        int m=Integer.parseInt(in[1]);
        String[] ide=new String[n];
        int[] fight=new int[n];
        boolean[] alive=new boolean[n];
        for(int i=0;i<n;++i){
            String[] t=sc.nextLine().split(" ");
            ide[i]=t[0];
            fight[i]=Integer.parseInt(t[1]);
            alive[i]=true;
        }
        int[][] meet=new int[m][2];
        boolean[][] tell=new boolean[m][2];
        for(int i=0;i<m;++i){
            String[] t=sc.nextLine().split(" ");
            meet[i][0]=Integer.parseInt(t[0])-1;
            meet[i][1]=Integer.parseInt(t[1])-1;
            tell[i][0]=t[2].equals("Y");
            tell[i][1]=t[3].equals("Y");
        }
        for(int i=0;i<m;++i){
            int u=meet[i][0];
            int v=meet[i][1];
            if(alive[u]&&alive[v]){
                String uide=ide[u];
                String vide=ide[v];
                boolean utell=tell[i][0];
                boolean vtell=tell[i][1];
                int powu=fight[u];
                int powv=fight[v];
                if(uide.equals("B")){
                    if(vide.equals("R")&&vtell&&powu>powv){
                        alive[v]=false;
                    }
                    if(utell&&vide.equals("R")){
                        if(powu>powv){
                            alive[v]=false;
                        }
                        else if(powu<powv){
                            alive[u]=false;
                        }
                        else{
                            alive[u]=false;
                            alive[v]=false;
                        }
                    }
                }
                else{
                    if(vide.equals("B")&&utell&&powu<powv){
                        alive[u]=false;
                    }
                    if(vtell&&vide.equals("B")){
                        if(powu>powv){
                            alive[v]=false;
                        }
                        else if(powu<powv){
                            alive[u]=false;
                        }
                        else{
                            alive[u]=false;
                            alive[v]=false;
                        }
                    }
                }
            }
        }
        for (boolean b : alive) {
            if(b){
                System.out.print("W");
            }
            else{
                System.out.print("L");
            }
        }
    }
}
        题目内容
小红给自己的队伍安排训练,分为红队和蓝队。但是每个人都不知道其他人是哪个队伍的。
接下来小红安排这些人进行战斗,第 i 个人的战斗力是 ai 。
两个人战斗时,每个人可以选择公开身份给对方,或者隐藏身份。
- 如果红队选手知道了本轮战斗的对手是蓝队选手,那么红队选手会直接攻击对方。
 - 如果蓝队选手知道了本来战斗的对手是红队选手,那么只有蓝队选手的战斗力高于对手时,他才会攻击对方。
 - 如果双方对手是同一队伍的(同为红队或同为蓝队)或者双方都不知道对方的身份,则双方都不会发动攻击。
 
如果两个人相互攻击,如果他们战斗力相同,则他们都失败了。否则战斗力高的一方胜利,战斗力低的一方失败。
你需要注意的是,一个已经失败的人参加之后的战斗,对应的战斗回合跳过。
现在小红想问你,按照小红给定的顺序进行战斗,最后有哪些人是 winner 还是 loser 。
如果一个人参与的所有战斗都是胜利的,则他是 winner ,否则他是 loser 。
输入描述
第一行,两个正整数 n 和 m(1≤n,m≤105) ,分别表示有 n 个人,m 轮战斗。
接下来的 n 行,第 i 行一个字符串 si 表示第 i 个人所在队伍,si 为 R 表示第 i 个人是红队选手,为 B 表示第 i 个人是蓝队选手, ai(1≤ai≤109) 表示第 i 个人的战斗力。
接下来的 m 行,第 i 行先是两个整数 x 和 y(1≤x,y≤n) ,表示小红第 i 个回合安排第 x 个人和第 y 个人战斗,接下来两个字符 c1,c2 表示 x,y 所在的队伍。
c1 为 Y 表示 x 公开身份,为 N 表示 x 隐藏身份。c2 为 Y 表示 y 公开身份,为 N 表示 y 隐藏身份。
输出描述
一行字符串,第 i 个字符为 W 表示第 i 个人是 winner ,第 i 个字符为 L 表示第 i 个人是 loser 。
样例
输入
4 4
R 8
B 1
R 9
B 10
1 2 N N
2 3 N Y
3 4 Y N
1 3 Y N
输出
WWLW
说明
第一轮战斗,双方都不公开身份,都不发动攻击。
第二轮战斗,3 号向 2 号公开身份,2 号是蓝色选手,其战斗力低于 3 号红色选手的战斗力,不发动攻击。
第三轮战斗,3 号向 4 号公开身份,4 号蓝色选手,直接发动攻击,其战斗力高于 3 号红色选手的战斗力,3 号失败,4 号胜利。
第四轮战斗,1 号向 3 号公开身份,3 号红色选手发现 1 号也是红色选手,不发动攻击。
最后 1,2,4 是 winner ,3 是 loser