注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

时光机TimeMachine

——一个退役OIer

 
 
 

日志

 
 

[BZOJ1972][Sdoi2010]猪国杀  

2014-11-18 22:09:18|  分类: Problems |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

1972: [Sdoi2010]猪国杀

发现智商题都不会做了,于是干脆去刷无脑模拟
写了两个下午+一晚上,调了半个晚上。。
其实写这玩意也是要动不少脑子
我想了好久怎么把三种猪的各种函数写到一起
最后DEBUG的时候发现少考虑了不少情况,然后桃的部分还写成了“可以别人给桃”
也算是达成人生成就了。。
然后中间还被JBR鄙视了:"你写这种东西就是消磨时间,还不如去颓废"
代码太长就不在下面写东西了
似乎有一个数据有问题,写的时候如果牌堆没牌了要取牌堆最后一个用

/*----------------------/*
2014年11月14日11:36:59
PigsKingdomKill Version 0.1
/*----------------------*/
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<algorithm>
#include<vector>
#include<iostream>

#define Sha 1
#define Shan 2
#define Tao 3

#define JD 4
#define NMRQ 5
#define WJQF 6
#define WXKJ 7

#define ZGLN 8
//打开后开启DEBUG模式
//#define DEBUG

/*
杀(K)
闪(D)
桃(P)

决斗(F)
南猪入侵(N)
万箭齐发(W)
无懈可击(J)

猪哥连弩(Z)
*/
// K D P F N W J Z
short UseLimit[10][10]={{0,1,0,1,1,1,1,0,1}, //主动出牌
{0,0,1,0,0,0,0,0,0},//K
{0,0,0,0,0,0,0,0,0},//D
{0,0,0,1,0,0,0,0,0},//P
{0,1,0,0,0,0,0,0,0},//F
{0,1,0,0,0,0,0,0,0},//N
{0,0,1,0,0,0,0,0,0},//W
{0,0,0,0,0,0,0,1,0},//J
{0,0,0,0,0,0,0,0,0},//Z
};
int JtoG[10]={1,1,2};
int ACT[3][2]={{1+2,4+8},{1+2,4},{2,1}};
int n,m;
namespace Action{
bool CheckPig(int start_id,int type);
bool Used(int id,int type);
bool Ignore(int id,int to,int type = 0);
bool CheckCard(int id,int group=0,int situ=0,int mode=0);
int FindPig(int id,short act_mode,int item_bh,int rid=0,int len=0);
}
namespace Data{
short CardBH[100];
char CardName[10]={0,'K','D','P','F','N','W','J','Z'};
std::deque<short>CardQue;
std::deque<short>PigQue;
struct Hand;
struct Pig;
}
namespace Data{
int all,live;
int MP,FP;
struct Pig{
int hp;
short state,job,alive,eq;
//杀冷却
short hot;
std::vector<int>Card;
void fset(int a){
alive = 1;
if(!a)state = 1;
job = a;
if(a<2) MP++;
else FP++;
eq = 0;hp = 4;
hot = 0;
}
}pigs[15];
void preset(){
int i,j;
for(i=1;i<=8;i++)CardBH[CardName[i]]=i;
}

//【玩家队列相关】//

int StandTop(int id){
if(PigQue.empty()){std::cerr<<"NO PIG!\n"<<std::endl;return 0;}
//有可能死循环?
while(PigQue.front()!=id){
int now = PigQue.front();
PigQue.pop_front();
PigQue.push_back(now);
}return PigQue.front();
}
//下一个玩家
int NextPig(int last){
StandTop(last);
do{
last = PigQue.front();
PigQue.pop_front();
PigQue.push_back(last);
}while(Data::pigs[PigQue.front()].alive==0);
return PigQue.front();
}
//从玩家队列里删除某人
void DeletePig(int id){
int now = StandTop(id);
if(pigs[now].job==0)MP = 0;
if(pigs[now].job==1)MP--;
if(pigs[now].job==2)FP--;
pigs[now].alive=0;
//PigQue.pop_front();
}
void ClearPig(){
using namespace Data;
int left = PigQue.size(),now = PigQue.front();
do{
left--;
now = PigQue.front();
PigQue.pop_front();
if(pigs[now].alive)
PigQue.push_back(now);
}while(left);
}
}

namespace DEBUG{
int i,j;
void CardWait(){
j = Data::CardQue.size();
printf("CardInLine:\t[%d left]\n",j);
if(j > 20)j = 20;
for(i=0;i<j;i++)printf("%c ",Data::CardName[Data::CardQue[i]]);
if(j == 20)printf("...");
printf("\n");printf("\n");
}
void PigWait(){
j = Data::PigQue.size();
printf("PigInLine:\t[%d left]\n",j);
for(i=0;i<j;i++)printf("%d ",Data::PigQue[i]);
printf("\n");printf("\n");
}
void PigCards(int id){
j = Data::pigs[id].Card.size();
printf("[%d left] ",j);
for(i=0;i<j;i++){
printf("%c ",Data::CardName[Data::pigs[id].Card[i]]);
}
printf("\n");
}
void PigInf(int id){
if(id){
Data::Pig &pn = Data::pigs[id];
printf("Pigs:%d\n",id);
printf("Job : %d State : %d\n",pn.job,pn.state);
printf("[HP] %d\n",pn.hp);
printf("[ZB] %d\n",pn.eq);
printf("[ALIVE] %d\n",pn.alive);
printf("[Cards]:",pn.alive);PigCards(id);
}else{
for(int i=1;i<=Data::all;i++)PigInf(i);
}
}
}
namespace Action{
//表明身份
void Jump(int now){
using namespace Data;
if((pigs[now].state&(1+2+4))==0){
if(pigs[now].job == 1)pigs[now].state = 2;
if(pigs[now].job == 2)pigs[now].state = 4;
}
}
//检查Player状态 攻击用
int CheckState(int start_id,int end_id,int state){
int now = start_id;
do{
if(Data::pigs[now].state & state)return now;
now = Data::NextPig(now);
}while(now!=end_id);
return 0;
}
int CheckJob(int start_id,int end_id,int type,int item){
int now = start_id;
do{
if(JtoG[Data::pigs[now].job] == type)
if(CheckCard(now,0,item,1))
return now;
now = Data::NextPig(now);
}while(now!=end_id);
return 0;
}
//锦囊(递归用?)
//当id玩家使用锦囊时无懈可击的判断
//type(要挡下的东西)
// 0: 表敌意
// 1: 献殷勤
bool Ignore(int id,int to,int type){
if((Data::pigs[to].state&(1+2+4)) == 0)return 0;
int now;
if(now = FindPig(id,type+1,WXKJ,to)){
CheckCard(now,0,WXKJ);//Use it
//Update State
Jump(now);
return Ignore(now,to,type^1)^1;
}else return 0;
}
short JueDou(int from,int to){
if(Data::pigs[from].job == 0 && Data::pigs[to].job == 1)return 1;
if(!CheckCard(to,JtoG[Data::pigs[from].job],JD)) return 1;
else return JueDou(to,from) ^ 1;
}
/*
行动模式:
从某个玩家(job)开始寻找第一个符合(state)的玩家
act_mode:
1: help
2: attack
*/
//id:开始 rid:判断阵营
int FindPig(int id,short act_mode,int item_bh,int rid,int len){
using namespace Data;
if(!rid)rid = id;
if(len==0) len = id;
else{
int a;
a = NextPig(id);
for(int i=1;i<len;i++)
a = NextPig(a);
len = a;
}
int to;
if(!item_bh){
to = CheckState(id,len,ACT[pigs[rid].job][act_mode-1]);
//反猪的特有攻击模式
if(!to && pigs[rid].job == 2 && act_mode == 2)
to = CheckState(id,len,2);
}else{
int tmp = JtoG[pigs[rid].job];
if(act_mode == 2)tmp ^= 3;
to = CheckJob(id,len,tmp,item_bh);
}
return to;
}
void GetCard(int last,int num){
for(int i=1;i<=num;i++){
int tmp = Data::CardQue.front();
if(Data::CardQue.size() > 1)Data::CardQue.pop_front();
Data::pigs[last].Card.push_back(tmp);
}
}
//造成伤害
void Damage(int from,int id){
Data::pigs[id].hp--;
#ifdef DEBUG
printf("--%d hit %d--\n",from,id);
if(from == 3 && id == 4)
printf("this");
#endif
if(!Data::pigs[id].hp){
int now = id,to=0;

//if(Data::pigs[id].state & (1+2+4))
//to = FindPig(now,1,Tao,0,1);
if(CheckCard(now,0,Tao)){
//Use Card
//CheckCard(to,0,Tao);
Data::pigs[id].hp++;
}else{
//Dead
#ifdef DEBUG
printf("--%d was killed by %d--\n",id,from);
#endif
Data::DeletePig(id);
if(!(Data::MP && Data::FP))return;
if(Data::pigs[id].job == 1 && Data::pigs[from].job == 0){
while(!Data::pigs[from].Card.empty())Data::pigs[from].Card.pop_back();
Data::pigs[from].eq = 0;
//Data::pigs[from].clear();
#ifdef DEBUG
printf("--%d make a mistake--\n",from);
#endif
}
if(Data::pigs[id].job == 2){
GetCard(from,3);
#ifdef DEBUG
printf("--%d Good Job!--\n",from);
#endif
}
#ifdef DEBUG
DEBUG::PigWait();
#endif
}
}
}
//NMRQ & WJQF & WXKJ 地图炮
bool MapEffect(int id,int bh){
int now = id,to,tos;
Data::Pig &np = Data::pigs[id];
now = Data::NextPig(id);
do{//Each Pig
//Check WXKJ
if(!Ignore(id,now)){
//Check And Use Card
if(!CheckCard(now,0,bh)){
//受伤
Damage(id,now);
if(!(Data::MP && Data::FP))return 0;
//类反
if(Data::pigs[now].state == 1 && np.state == 0)
np.state = 8;
}
}
now = Data::NextPig(now);
}while(id!=now);
}
//使用卡牌
//situ:
// 0: normal
//situ 似乎可以去掉? 不能去掉! 杀的时候。。
bool Use(int id,int bh,int group,int situ=0){

Data::Pig &np = Data::pigs[id];
int to;
switch (bh){
case Sha:{//*
if(situ == NMRQ || situ == JD)return 1;
if(situ == 0 && !np.hot){
if(np.hot)return 0;
to = FindPig(id,2,0,0,2);
if(!to)return 0;
Jump(id);
if(!CheckCard(to,0,Sha))
Damage(id,to);
return 1;
}
return 0;
}
case Shan:{
if(situ == WJQF || situ == Sha) return 1;
return 0;
}
case Tao:{
if(situ == Tao)return 1;
//situ == 0
if(np.hp == 4)return 0;
else{
np.hp++;
return 1;
}
}
case JD:{//*
to = FindPig(id,2,0);
if(!to)return 0;
//Update State
Jump(id);
if(Ignore(id,to))return 1;
if(JueDou(id,to))Damage(id,to);
else Damage(to,id);
return 1;
}
case NMRQ:{//*
//Effect
MapEffect(id,NMRQ);
return 1;
}
case WJQF:{//*
//Effect
MapEffect(id,WJQF);
return 1;
}
case WXKJ:{//*
//Effect
/*
if(np.state==0)return 1
else return MapEffect(id,WXKJ);*/
return 1;
}
case ZGLN:{
Data::pigs[id].eq = 1;
Data::pigs[id].hot = 0;
return 1;
}
}
}
//检查是否有可用的牌,(mode 0 :使用 mode 1 :不使用)
bool CheckCard(int id,int group,int situ,int mode){
Data::Pig &np = Data::pigs[id];
int n = np.Card.size(),i,bh;
for(i=0;i<n;i++)
if(UseLimit[situ][np.Card[i]]){
if(mode)return 1;
bh = np.Card[i];
if(Use(id,bh,JtoG[np.job],situ)){
if(bh == Sha && np.eq==0 && situ == 0)
np.hot=1;

#ifdef DEBUG
printf("--%d used %c--\n",id,Data::CardName[bh]);
#endif
//移除
if(!np.Card.empty())
np.Card.erase(find(np.Card.begin(),np.Card.end(),bh));
return 1;
}
}
return 0;
}
//主循环
void Main(int last){
int R=0;
while(Data::MP&&Data::FP){
Data::ClearPig();
GetCard(last,2);
#ifdef DEBUG

printf("\n#Round %d [NOW:%d]\n",++R,last);
DEBUG::CardWait();
PigInf(0);
//if(R > 10)return;
#endif
if(R==4){
printf("DEBUG!");
}
//分配手牌
//出牌阶段
while(CheckCard(last) && Data::MP&&Data::FP){
#ifdef DEBUG
printf("\t===\n");
#endif
if(Data::pigs[last].alive == 0)break;
}
//冷却杀
Data::pigs[last].hot = 0;
//Next
last = Data::NextPig(last);
}
}
}
int main(){
// freopen("in.txt","r",stdin);
#ifdef DEBUG
freopen("in.txt","r",stdin);
//freopen("debug.txt","w",stdout);
#endif
int i,j,start;char cc,str[6];
Data::preset();
scanf("%d %d",&n,&m);
Data::all = n;
//GameReady
for(i=1;i<=Data::all;i++){
scanf("%s",str);
if(str[0]=='M')Data::pigs[i].fset(0),start = i;
if(str[0]=='Z')Data::pigs[i].fset(1);
if(str[0]=='F')Data::pigs[i].fset(2);
for(j=1;j<=4;j++){
scanf(" %c",&cc);
Data::pigs[i].Card.push_back(Data::CardBH[cc]);
}
Data::PigQue.push_back(i);
}
for(i=1;i<=m;i++){
scanf(" %c",&cc);
Data::CardQue.push_back(Data::CardBH[cc]);
}
#ifdef DEBUG
//DEBUG::CardWait();
#endif

//GameStart
Action::Main(start);

//GameEnd..
if(Data::MP)printf("MP\n");
else printf("FP\n");

for(i=1;i<=Data::all;i++)
if(Data::pigs[i].alive){
for(j=0;j<Data::pigs[i].Card.size();j++){
if(j)printf(" ");
printf("%c",Data::CardName[Data::pigs[i].Card[j]]);
}
printf("\n");
}else printf("DEAD\n");
return 0;
}


  评论这张
 
阅读(32)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017