LOJ#2885. 「SDOI2010」猪国杀

news/2024/9/18 20:24:25/文章来源:https://www.cnblogs.com/huyufeifei/p/18414923

对拍器在此。https://www.luogu.com/discuss/81283

献忠!

AC代码

mod oiread {use std::{io::{stdin, Read},ops::{Add, Mul, Neg},};pub fn next() -> u8 {let mut a = stdin().lock();let mut c = [0u8];match a.read(&mut c) {Ok(0) => b'\n', // End Of FileOk(1) => c[0],_ => panic!(),}}pub fn get_char() -> char {next().into()}pub fn read_inum<T>() -> TwhereT: Add<Output = T> + Mul<Output = T> + From<u8> + Neg<Output = T>,{let mut ans: T = T::from(0);let mut flag = false;let mut c = next();while c < b'0' || c > b'9' {if c == b'-' {flag = true;}c = next();}while c >= b'0' && c <= b'9' {ans = ans * T::from(10) + T::from(c - b'0');c = next();}if flag {-ans} else {ans}}pub fn read_unum<T>() -> TwhereT: Add<Output = T> + Mul<Output = T> + From<u8>,{let mut ans: T = T::from(0);let mut c = next();while c < b'0' || c > b'9' {c = next();}while c >= b'0' && c <= b'9' {ans = ans * T::from(10) + T::from(c - b'0');c = next();}ans}pub fn read_i64() -> i64 {read_inum::<i64>()}pub fn read_str() -> String {let mut res = String::new();let mut c = next();while c == b' ' || c == b'\n' || c == b'\r' {c = next();}while c != b' ' && c != b'\n' && c != b'\r' {res.push(c as char);c = next();}res}pub fn read_u8s() -> Vec<u8> {let mut res = Vec::new();let mut c = next();while c == b' ' || c == b'\n' || c == b'\r' {c = next();}while c != b' ' && c != b'\n' && c != b'\r' {res.push(c);c = next();}res}
}use std::collections::VecDeque;
use std::fmt;
use std::fmt::Display;
use std::mem::swap;
use std::process::exit;use oiread::read_i64 as read;
use oiread::read_str;#[derive(PartialEq, Eq, Clone, Copy)]
enum BaseType {Atk,Def,Peach,
}
impl From<String> for BaseType {fn from(value: String) -> Self {match value.as_str() {"P" => BaseType::Peach,"K" => BaseType::Atk,"D" => BaseType::Def,x => panic!("Base Card Type Error : {}", x),}}
}
impl Display for BaseType {fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {write!(f,"{}",match *self {BaseType::Atk => "K",BaseType::Def => "D",BaseType::Peach => "P",})}
}#[derive(PartialEq, Eq, Clone, Copy)]
enum SkillType {Fight,ReqAtk,ReqDef,Cancel,
}
impl From<String> for SkillType {fn from(value: String) -> Self {match value.as_str() {"F" => SkillType::Fight,"N" => SkillType::ReqAtk,"W" => SkillType::ReqDef,"J" => SkillType::Cancel,x => panic!("Skill Card Type Error : {}", x),}}
}
impl Display for SkillType {fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {write!(f,"{}",match *self {SkillType::Fight => "F",SkillType::ReqAtk => "N",SkillType::ReqDef => "W",SkillType::Cancel => "J",})}
}#[derive(PartialEq, Eq, Clone, Copy)]
enum CardType {Base(BaseType),Skill(SkillType),Equip,
}
impl From<String> for CardType {fn from(value: String) -> Self {match value.as_str() {"P" | "K" | "D" => CardType::Base(value.into()),"F" | "N" | "W" | "J" => CardType::Skill(value.into()),"Z" => CardType::Equip,x => panic!("Card Type Error : {}", x),}}
}
impl Display for CardType {fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {match *self {CardType::Base(card) => write!(f, "{}", card),CardType::Skill(card) => write!(f, "{}", card),CardType::Equip => write!(f, "Z"),}}
}
#[cfg(feature = "debug")]
impl CardType {fn show(&self) -> &'static str {match *self {CardType::Base(card) => match card {BaseType::Atk => "杀",BaseType::Def => "闪",BaseType::Peach => "桃",},CardType::Skill(card) => match card {SkillType::Fight => "决斗",SkillType::ReqAtk => "南蛮入侵",SkillType::ReqDef => "万箭齐发",SkillType::Cancel => "无懈可击",},CardType::Equip => "诸葛连弩",}}
}#[derive(PartialEq, Debug, Clone, Copy)]
enum Identity {MainPig,ZhongPig,FanPig,
}
impl From<String> for Identity {fn from(value: String) -> Self {match value.as_str() {"MP" => Self::MainPig,"ZP" => Self::ZhongPig,"FP" => Self::FanPig,x => panic!("Error Pig Identity: {}", x),}}
}
#[cfg(feature = "debug")]
impl Identity {fn show(&self) -> &'static str {match *self {Identity::MainPig => "主公",Identity::ZhongPig => "忠臣",Identity::FanPig => "反贼",}}
}#[derive(Clone, Copy, PartialEq, Eq)]
enum ActType {None,Zhong,Fan,
}#[derive(PartialEq, Eq, Clone, Copy)]
enum State {None,SimFan,Fan,Zhong,
}
#[cfg(feature = "debug")]
impl State {fn show(&self) -> &'static str {match *self {State::None | State::SimFan => "    ",State::Fan | State::Zhong => "暴露",}}
}#[derive(Clone, Copy)]
struct Act {tp: ActType,card: CardType,src: usize,dst: Option<usize>,
}
impl Act {fn new(tp: ActType, card: CardType, src: usize, dst: Option<usize>) -> Self {Self { tp, card, src, dst }}
}struct Pig {tp: Identity,hp: isize,pos: usize,state: State,cards: Vec<CardType>,equip: bool,alive: bool,attacked: bool,
}
impl Pig {const MAX_HP: isize = 4;fn new(pos: usize) -> Self {let tp = Identity::from(read_str());if pos == 0 {assert_eq!(tp, Identity::MainPig);}let mut cards = Vec::new();for _ in 0..4 {cards.push(CardType::from(read_str()));}Self {tp,hp: Self::MAX_HP,state: State::None,cards,pos,equip: false,alive: true,attacked: false,}}fn is_known(&self) -> bool {self.tp == Identity::MainPig || self.state == State::Zhong || self.state == State::Fan}fn get_card(&mut self, pool: &mut Pool, cnt: usize) {for _ in 0..cnt {if let Some(c) = pool.get() {self.cards.push(c);}}}fn get_enemy(&self, players: &Vec<Pig>) -> Option<usize> {if Identity::FanPig == self.tp {return Some(0);}// [self.pos+1, self.pos+2, ... n-1, 0, 1, 2, ... self.pos-1 ]let mut range = (0..players.len()).collect::<Vec<usize>>();range.rotate_left(self.pos + 1);for i in range {if i == self.pos || !players[i].alive {continue;}let pig = &players[i];match self.tp {Identity::MainPig => {if let State::Fan | State::SimFan = pig.state {return Some(i);}}Identity::ZhongPig => {if State::Fan == pig.state {return Some(i);}}Identity::FanPig => unreachable!(),}}None}fn get_enemy_dis1(&self, players: &Vec<Pig>) -> Option<usize> {// [self.pos+1, self.pos+2, ... n-1, 0, 1, 2, ... self.pos-1 ]let mut range = (0..players.len()).collect::<Vec<_>>();range.rotate_left(self.pos + 1);for i in range {if i == self.pos || !players[i].alive {continue;}let pig = &players[i];match self.tp {Identity::MainPig => {if let State::Fan | State::SimFan = pig.state {return Some(i);}}Identity::ZhongPig => {if State::Fan == pig.state {return Some(i);}}Identity::FanPig => {if State::Zhong == pig.state || pig.tp == Identity::MainPig {return Some(i);}}}break;}None}fn ask(&self, asked_card: CardType) -> Option<usize> {for (i, card) in self.cards.iter().enumerate() {if *card == asked_card {return Some(i);}}None}fn try_act(&self, players: &Vec<Pig>) -> Option<(usize, Act)> {for i in 0..self.cards.len() {let card = &self.cards[i];match card {CardType::Equip => {return Some((i, Act::new(ActType::None, CardType::Equip, self.pos, None)));}CardType::Base(card) => match card {BaseType::Atk => {if !self.equip && self.attacked {continue;}let enemy = self.get_enemy_dis1(players);if enemy.is_some() {return Some((i,Act::new(match self.tp {Identity::MainPig => ActType::None,Identity::ZhongPig => ActType::Zhong,Identity::FanPig => ActType::Fan,},CardType::Base(BaseType::Atk),self.pos,enemy,),));}}BaseType::Def => {}BaseType::Peach => {if self.hp != Self::MAX_HP {return Some((i,Act::new(ActType::None,CardType::Base(BaseType::Peach),self.pos,Some(self.pos),),));}}},CardType::Skill(card) => match card {SkillType::Fight => {let enemy = self.get_enemy(players);if enemy.is_some() {return Some((i,Act::new(match self.tp {Identity::MainPig => ActType::None,Identity::ZhongPig => ActType::Zhong,Identity::FanPig => ActType::Fan,},CardType::Skill(SkillType::Fight),self.pos,enemy,),));}}SkillType::ReqAtk => {return Some((i,Act::new(ActType::None,CardType::Skill(SkillType::ReqAtk),self.pos,None,),))}SkillType::ReqDef => {return Some((i,Act::new(ActType::None,CardType::Skill(SkillType::ReqDef),self.pos,None,),))}SkillType::Cancel => {}},}}None}
}fn main() {let (n, m) = (read() as usize, read() as usize);let mut players = Vec::new();for i in 0..n {players.push(Pig::new(i));}let mut pool = Pool::new(m);// game startloop {for now_pig_id in 0..players.len() {if !players[now_pig_id].alive {continue;}// turn start#[cfg(feature = "debug")]println!("Begin: {} // {}", now_pig_id + 1, players[0].cards.len());players[now_pig_id].attacked = false;players[now_pig_id].get_card(&mut pool, 2);#[cfg(feature = "debug")]show(&mut players);loop {if !players[now_pig_id].alive {break;}let act = players[now_pig_id].try_act(&players);if act.is_none() {break;}let (card_id, act) = act.unwrap();players[now_pig_id].cards.remove(card_id);assert_eq!(act.src, now_pig_id);// use cardmatch act.tp {ActType::None => {}ActType::Zhong => players[now_pig_id].state = State::Zhong,ActType::Fan => players[now_pig_id].state = State::Fan,}match act.card {CardType::Base(card) => match card {BaseType::Atk => {assert!(act.dst.is_some());players[now_pig_id].attacked = true;let d = act.dst.unwrap();let t = players[d].ask(CardType::Base(BaseType::Def));if let Some(card_id) = t {players[d].cards.remove(card_id);} else {players[d].hp -= 1;check_dead(&mut players, &mut pool, now_pig_id, d);}}BaseType::Peach => {assert!(players[now_pig_id].hp < Pig::MAX_HP);players[now_pig_id].hp += 1;}BaseType::Def => unreachable!(),},CardType::Skill(card) => match card {SkillType::Fight => {#[cfg(feature = "debug")]println!("决斗!->{} // {}",act.dst.unwrap() + 1,players[0].cards.len());// check Cancelassert!(act.dst.is_some());let effect = check_cancel(act, &mut players);if effect {let mut wait = now_pig_id;let mut now = act.dst.unwrap();loop {if wait == 0 && players[now].tp == Identity::ZhongPig {break;}let t = players[now].ask(CardType::Base(BaseType::Atk));if t.is_none() {break;};players[now].cards.remove(t.unwrap());swap(&mut now, &mut wait);}players[now].hp -= 1;check_dead(&mut players, &mut pool, wait, now);}}SkillType::ReqAtk => {// loop every pig, check Cancel, req atklet s = now_pig_id;// s+1, s+2 .. n-1 0 1 .. s-1let mut range = (0..players.len()).collect::<Vec<_>>();range.rotate_left(s + 1);for i in range {if !players[i].alive || i == s {continue;}let effect = check_cancel(Act::new(ActType::None,CardType::Skill(SkillType::ReqAtk),s,Some(i),),&mut players,);#[cfg(feature = "debug")]println!("effect = {effect} // {}", players[0].cards.len());if !effect {continue;}let t = players[i].ask(CardType::Base(BaseType::Atk));if let Some(card_id) = t {players[i].cards.remove(card_id);} else {players[i].hp -= 1;check_dead(&mut players, &mut pool, s, i);}}}SkillType::ReqDef => {// same as beforelet s = now_pig_id;// s+1, s+2 .. n-1 0 1 .. s-1let mut range = (0..players.len()).collect::<Vec<_>>();range.rotate_left(s + 1);for i in range {if !players[i].alive || i == s {continue;}let effect = check_cancel(Act::new(ActType::None,CardType::Skill(SkillType::ReqDef),s,Some(i),),&mut players,);if !effect {continue;}let t = players[i].ask(CardType::Base(BaseType::Def));if let Some(card_id) = t {players[i].cards.remove(card_id);} else {players[i].hp -= 1;check_dead(&mut players, &mut pool, s, i);}}}SkillType::Cancel => unreachable!(),},CardType::Equip => {players[now_pig_id].equip = true;}}// end card//println!("use card : {} to {:?}", act.card, act.dst);}// end turn//println!("end turn.------------------------");//out_result(&players);}}
}fn check_cancel(act: Act, players: &mut Vec<Pig>) -> bool {let mut now_act = act;let mut effect = true;loop {let res = who_use_cancel(now_act, players);if res.is_none() {break;}let (i, j, tp) = res.unwrap();players[i].cards.remove(j);#[cfg(feature = "debug")]println!("{}:无懈可击! // {}", i + 1, players[0].cards.len());effect = !effect;now_act = Act::new(tp, CardType::Skill(SkillType::Cancel), i, Some(now_act.src));}effect
}fn who_use_cancel(act: Act, players: &mut Vec<Pig>) -> Option<(usize, usize, ActType)> {assert!(act.dst.is_some());let s = act.src;let t = act.dst.unwrap();if !players[t].is_known() && !players[s].is_known() {// both unknownreturn None;}// s, s+1, ..., n-1, 0, 1, ..., s-1let mut range = (0..players.len()).collect::<Vec<_>>();range.rotate_left(s);for i in range {if !players[i].alive {continue;}match players[i].tp {Identity::MainPig | Identity::ZhongPig => {if ((players[t].state == State::Zhong || players[t].tp == Identity::MainPig)&& (act.tp != ActType::Zhong))|| act.tp == ActType::Fan{for j in 0..players[i].cards.len() {if players[i].cards[j] == CardType::Skill(SkillType::Cancel) {if players[i].tp != Identity::MainPig {players[i].state = State::Zhong;}return Some((i, j, ActType::Zhong));}}}}Identity::FanPig => {if (players[t].state == State::Fan && act.tp != ActType::Fan)|| act.tp == ActType::Zhong{for j in 0..players[i].cards.len() {if players[i].cards[j] == CardType::Skill(SkillType::Cancel) {players[i].state = State::Fan;return Some((i, j, ActType::Fan));}}}}}}None
}fn check_dead(players: &mut Vec<Pig>, pool: &mut Pool, src: usize, dst: usize) {if players[dst].tp == Identity::MainPig && players[src].state == State::None {players[src].state = State::SimFan;}if players[dst].hp <= 0 {let t = players[dst].ask(CardType::Base(BaseType::Peach));if let Some(card_id) = t {players[dst].cards.remove(card_id);players[dst].hp += 1;} else {players[dst].alive = false;players[dst].cards.clear();players[dst].equip = false;// check resultcheck_game_over(players);if players[dst].tp == Identity::FanPig {players[src].get_card(pool, 3);} else if players[dst].tp == Identity::ZhongPig && src == 0 {players[0].cards.clear();players[0].equip = false;}}}
}fn check_game_over(players: &Vec<Pig>) {if !players[0].alive {// game over; FP winprintln!("FP");out_result(players);exit(0);}for pig in players {if pig.tp == Identity::FanPig && pig.alive {return;}}// game over; MP winprintln!("MP");out_result(players);exit(0);
}fn out_result(players: &Vec<Pig>) {for pig in players {if pig.alive {println_card(&pig.cards);} else {println!("DEAD");}}
}fn println_card(cards: &Vec<CardType>) {for (i, card) in cards.iter().enumerate() {print!("{}", card);if i < cards.len() - 1 {print!(" ");}}println!("");
}struct Pool {pool: VecDeque<CardType>,last: Option<CardType>,
}
impl Pool {fn new(cnt: usize) -> Self {let mut pool = VecDeque::new();for _ in 0..cnt {pool.push_back(CardType::from(read_str()));}Self { pool, last: None }}// data is wrong.// if pool is empty, return the last card.fn get(&mut self) -> Option<CardType> {if !self.pool.is_empty() {self.last = self.pool.pop_front();}return self.last;}
}#[cfg(feature = "debug")]
fn show(players: &mut Vec<Pig>) {for i in 0..players.len() {print!("{}:{{{}}}({})hp:",i + 1,players[i].tp.show(),players[i].state.show());for _ in 0..players[i].hp {print!("*");}for x in &players[i].cards {print!("【{}】", x.show());}println!();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/797322.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【极速下载】Vmware17.5.2官方最新版本2024网盘下载

Mware简介VMware 是一款强大的虚拟化软件。它能在一台物理机上同时运行多个操作系统,实现资源高效利用。可用于服务器虚拟化、桌面虚拟化等。提高系统可靠性、可扩展性与安全性,降低成本和管理复杂度。VMware广泛应用于企业数据中心和云计算领域,是 IT 重要工具。 VMware最…

Junior.Crypt.2024 CTF - Forensics

补充学习了有关evtx以及注册表的知识Junior.Crypt.2024 CTF - Forensics 部分题目复现参考: https://blog.jacki.cn/2024/07/05/Junior_Crypt_2024_CTF/#SAMBO-wrestler https://yocchin.hatenablog.com/entry/2024/07/08/124230 标注“#”表示未复现,日后有机会补上吧 题目地…

全网最适合入门的面向对象编程教程:49 Python函数方法与接口-函数与方法的区别和lamda匿名函数

在 Python 中,函数和方法都是代码的基本单元,用于封装和执行特定的任务。它们之间有一些重要的区别,而 lambda 匿名函数则是 Python 提供的一种简洁定义小型函数的方法。全网最适合入门的面向对象编程教程:49 Python 函数方法与接口-函数与方法的区别和 lamda 匿名函数摘要…

基于 CrewAI 多智能体框架,手把手构建一个自动化写作应用实战

利用 CrewAI 多智能体框架,我们可以更细粒度的控制智能体和任务,通过不同的流程组织协同多智能体共同完成工作……明月皓皓,星河灿烂,中秋佳节,团圆美满。祝大家中秋节快乐!听说台风要来了,也不知道还能不能吃着月饼赏个月?老牛同学在上文(Agent(智能体)和 MetaGPT,一…

【推荐 - 源码安装】nginx - 安装

准备查看操作系统的版本信息[root@lab10 ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core)查看操作系统的网卡地址[root@lab10 ~]# ip address show ens32 2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group de…

痞子衡嵌入式:JLink命令行以及JFlash对于下载算法的作用地址范围认定

大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是JLink命令行以及JFlash对于下载算法的作用地址范围认定。最近痞子衡在给一个 RT1170 客户定制一个 Infineon MirrorBit 类型 64MB Flash 的 SEGGER 下载算法,做完之后在 JFlash 下测试小数据下载没有问题,但…

软件工程导论——个人项目之论文查重

软件工程导论——个人项目之论文查重这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/CSGrade22-12/这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/CSGrade22-12/homework/13220这个作业的目标 设计一个论文查重算法并实现;学会 Git 版本控制Github仓库…

主从库与切片集群机制

主从库与切片集群机制 主从复制源码剖析 redis的主从复制主要包括全量复制RDB文件,增量复制,长连接同步,使用了基于状态机的设计思想,来实现不同状态和状态间的跳转 基于状态机实现的话,在开发程序时只需要考虑不同状态下具体要执行的操作,以及状态之间的跳转条件即可 四…

数据类型与底层原理

数据类型与底层原理 数据结构 哈希表 redis使用链式哈希来解决哈希冲突,其Hash表实质上是一个二维数组,其中每一项就是一个指向哈希项(dictEntry)的指针 typedef struct dictht {dictEntry **table; //二维数组unsigned long size; //Hash表大小unsigned long sizemask;uns…