80pts,WA 在 #10, 12, 20, 21
查看原帖
80pts,WA 在 #10, 12, 20, 21
768951
_Chronostatis_楼主2024/1/24 14:47

rt.

#include <bits/stdc++.h>

using namespace std;

#define CRD_USED true
#define CRD_CAN_USE false
#define PIG_DEAD true
#define PIG_NOT_DEAD false
#define PIG_JUMPED true
#define PIG_NOT_JUMPED false
#define PIG_LIKE_BAD true
#define PIG_NOT_LIKE_BAD false
#define HAVE_Z true
#define NOT_HAVE_Z false

struct Card {
  char crd;
  bool used;
};

Card crds[2010];
int n, m, np, top = 1;
char tp[15];

struct Pig {
  int hp, id;
  bool usedK, haveZ, jumped, likeBad, dead;
  string type;
  vector<Card> card;
  Pig() {
    hp = 4;
    dead = PIG_NOT_DEAD;
    jumped = PIG_NOT_JUMPED;
    haveZ = NOT_HAVE_Z;
    likeBad = PIG_NOT_LIKE_BAD;
    usedK = CRD_CAN_USE;
  }
  void TakeCard();
  void ClearCard();
  void DelCard(int);
  int FindTo(char);
  int FindCard(char);
  void UseCard(Card &);
  void Die(int);
  void Hurt(int);
  bool CanUse(char);
  bool Resp(char);
  void Jump();
  bool FindJ(int);
  bool BackJ(int);
  void Turn();
  void K(int);
  void F(int);
  void N();
  void W();
} pg[15];
void Pig::TakeCard() {
  card.push_back(crds[top++]);
  top = min(top, m);
}
void Pig::ClearCard() {
  card.clear();
  haveZ = NOT_HAVE_Z;
}
void Pig::DelCard(int crd) { card[crd].used = CRD_USED; }
int Pig::FindTo(char crd) {
  if (crd == 'K') {
    if (usedK == CRD_USED && haveZ == NOT_HAVE_Z)
      return 0;
    if (type == "MP") {
      for (int i = id % n + 1; i != id; i = i % n + 1) {
        if (pg[i].dead == PIG_DEAD) {
          continue;
        }
        if (pg[i].likeBad == PIG_LIKE_BAD ||
            (pg[i].type == "FP" && pg[i].jumped == PIG_JUMPED)) {
          return i;
        } else {
          return 0;
        }
      }
    } else if (type == "ZP") {
      for (int i = id % n + 1; i != id; i = i % n + 1) {
        if (pg[i].dead == PIG_DEAD) {
          continue;
        }
        if (pg[i].type == "FP" && pg[i].jumped == PIG_JUMPED) {
          return i;
        } else {
          return 0;
        }
      }
    } else if (type == "FP") {
      for (int i = id % n + 1; i != id; i = i % n + 1) {
        if (pg[i].dead == PIG_DEAD) {
          continue;
        }
        if (pg[i].type != "FP" && pg[i].jumped == PIG_JUMPED) {
          return i;
        } else {
          return 0;
        }
      }
    }
  } else if (crd == 'F') {
    if (type == "MP") {
      for (int i = id % n + 1; i != id; i = i % n + 1) {
        if (pg[i].dead == PIG_DEAD) {
          continue;
        }
        if (pg[i].likeBad == PIG_LIKE_BAD ||
            (pg[i].type == "FP" && pg[i].jumped == PIG_JUMPED)) {
          return i;
        }
      }
    } else if (type == "ZP") {
      for (int i = id % n + 1; i != id; i = i % n + 1) {
        if (pg[i].dead == PIG_DEAD) {
          continue;
        }
        if (pg[i].type == "FP" && pg[i].jumped == PIG_JUMPED) {
          return i;
        }
      }
    } else if (type == "FP") {
      return 1;
    }
    return 0;
  }
}
int Pig::FindCard(char crd) {
  for (int i = 0; i < card.size(); i++) {
    if (card[i].used != CRD_USED && card[i].crd == crd) {
      return i;
    }
  }
  return -1;
}
void Pig::UseCard(Card &crd) {
  if (crd.crd == 'K') {
    int x = FindTo('K');
    if (x) {
      crd.used = CRD_USED;
      K(x);
    }
  } else if (crd.crd == 'P') {
    if (hp < 4) {
      crd.used = CRD_USED;
      hp++;
    }
  } else if (crd.crd == 'F') {
    int x = FindTo('F');
    if (x) {
      crd.used = CRD_USED;
      F(x);
    }
  } else if (crd.crd == 'N') {
    crd.used = CRD_USED;
    N();
  } else if (crd.crd == 'W') {
    crd.used = CRD_USED;
    W();
  } else if (crd.crd == 'Z') {
    crd.used = CRD_USED;
    haveZ = HAVE_Z;
  }
}
void Over(string winner) {
  cout << winner << '\n';
  for (int i = 1; i <= n; i++) {
    if (pg[i].dead == PIG_DEAD) {
      cout << "DEAD";
    } else {
      for (int j = 0; j < pg[i].card.size(); j++) {
        if (pg[i].card[j].used == CRD_CAN_USE) {
          cout << pg[i].card[j].crd << ' ';
        }
      }
    }
    cout << '\n';
  }
  exit(0);
}
void Pig::Die(int pig) {
  dead = PIG_DEAD;
  if (type == "MP") {
    Over("FP");
  } else if (type == "FP") {
    np--;
    if (!np) {
      Over("MP");
    }
    for (int i = 1; i <= 3; i++) {
      pg[pig].TakeCard();
    }
  } else if (type == "ZP" && pg[pig].type == "MP") {
    pg[pig].ClearCard();
    pg[pig].haveZ = NOT_HAVE_Z;
  }
}
void Pig::Hurt(int pig) {
  hp--;
  if (!hp) {
    int x = FindCard('P');
    if (x == -1) {
      Die(pig);
    } else {
      DelCard(x);
      hp++;
    }
  }
}
bool Pig::CanUse(char crd) {
  if (crd == 'P' && hp < 4)
    return 1;
  if ((crd == 'K' && FindTo('K')) || (crd == 'F' && FindTo('F')) ||
      crd == 'N' || crd == 'W' || crd == 'Z')
    return 1;
  return 0;
}
bool Pig::Resp(char crd) {
  int x;
  if (crd == 'K' || crd == 'W') {
    x = FindCard('D');
  } else if (crd == 'N') {
    x = FindCard('K');
  }
  if (x == -1)
    return 0;
  DelCard(x);
  return 1;
}
void Pig::Jump() { jumped = PIG_JUMPED; }
bool Pig::FindJ(int killer) {
  if (jumped == PIG_NOT_JUMPED)
    return 0;
  bool first = 1;
  for (int i = killer; i != killer || first; i = i % n + 1) {
    first = 0;
    if (pg[i].dead == PIG_DEAD || (type != "FP" && pg[i].type == "FP") ||
                     (type == "FP" && pg[i].type != "FP")) {
      continue;
    }
    int x = pg[i].FindCard('J');
    if (x != -1) {
      pg[i].DelCard(x);
      pg[i].Jump();
      return !pg[i].BackJ(id);
    }
  }
  return 0;
}
bool Pig::BackJ(int pig) {
  for (int i = id % n + 1; i != id; i = i % n + 1) {
    if (pg[i].dead == PIG_DEAD) {
      continue;
    }
    if (type == "ZP" && pg[i].type == "MP" ||
        type == "MP" && pg[i].type == "ZP") {
      continue;
    }
    if (type == "FP" && pg[i].type == "FP") {
      continue;
    }
    int x = pg[i].FindCard('J');
    if (x != -1) {
      pg[i].DelCard(x);
      pg[i].Jump();
      return !pg[pig].FindJ(i);
    }
  }
  return 0;
}
void Pig::Turn() {
  TakeCard(), TakeCard();
  bool usedCard = 1;
  while (usedCard) {
    usedCard = 0;
    for (int i = 0; i < card.size(); i++) {
      if (card[i].used == CRD_USED) {
        continue;
      }
      if (!CanUse(card[i].crd)) {
        continue;
      }
      UseCard(card[i]);
      if (dead == PIG_DEAD) {
        return;
      }
      i = -1;
      usedCard = 1;
    }
  }
  pg[id].usedK = CRD_CAN_USE;
}
void Pig::K(int pig) {
  if (usedK == CRD_USED && haveZ == NOT_HAVE_Z)
    return;
  Jump();
  likeBad = PIG_NOT_LIKE_BAD;
  usedK = CRD_USED;
  if (!pg[pig].Resp('K')) {
    pg[pig].Hurt(id);
  }
}

void Pig::F(int pig) {
  Jump();
  likeBad = PIG_NOT_LIKE_BAD;
  if (pg[pig].FindJ(id))
    return;
  if (type == "MP" && pg[pig].type == "ZP") {
    pg[pig].Hurt(id);
    return;
  }
  int victim;
  while (1) {
    int x = pg[pig].FindCard('K');
    if (x == -1) {
      victim = 2;
      break;
    } else {
      pg[pig].DelCard(x);
    }
    x = FindCard('K');
    if (x == -1) {
      victim = 1;
      break;
    } else {
      DelCard(x);
    }
  }
  if (victim == 2) {
    pg[pig].Hurt(id);
  } else if (victim == 1) {
    Hurt(pig);
  }
}

void Pig::N() {
  for (int i = id % n + 1; i != id; i = i % n + 1) {
    if (pg[i].dead == PIG_DEAD) {
      continue;
    }
    if (pg[i].FindJ(id)) {
      continue;
    }
    if (!pg[i].Resp('N')) {
      pg[i].Hurt(id);
      if (pg[i].type == "MP" && jumped == PIG_NOT_JUMPED) {
        likeBad = PIG_LIKE_BAD;
      }
    }
  }
}

void Pig::W() {
  for (int i = id % n + 1; i != id; i = i % n + 1) {
    if (pg[i].dead == PIG_DEAD)
      continue;
    if (pg[i].FindJ(id))
      continue;
    if (!pg[i].Resp('W')) {
      pg[i].Hurt(id);
      if (pg[i].type == "MP" && jumped == PIG_NOT_JUMPED) {
        likeBad = PIG_LIKE_BAD;
      }
    }
  }
}

int main() {
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    cin >> pg[i].type;
    pg[i].id = i;
    np += (pg[i].type == "FP");
    for (int j = 1; j <= 4; j++) {
      Card crd;
      cin >> crd.crd;
      pg[i].card.push_back({crd.crd, CRD_CAN_USE});
    }
  }
  for (int i = 1; i <= m; i++) {
    Card crd;
    cin >> crd.crd;
    crds[i] = {crd.crd, CRD_CAN_USE};
  }
  pg[1].Jump();
  for (int i = 1;; i = i % n + 1) {
    if (pg[i].dead == PIG_NOT_DEAD) {
      pg[i].Turn();
    }
  }
  return 0;
}
2024/1/24 14:47
加载中...