http://cxsjsx.openjudge.cn/warcraftpractice/1/
这个题,,怎么说呢,大bug不解释。。
超级模拟有木有。。
第一:看清题目!!!!!!
第二,如果你是直接从装备跳到终极版的话,建议你先去做一做行军
传送门: http://poj.grids.cn/practice/3750/ 和http://poj.org/problem?id=3760
难度较小。
行军版我的AC代码:
http://blog.csdn.net/ckcz123/article/details/8729135
第三,如果你总是总是WA的话,给你一个方法。
去下一个UltraCompare软件,
下载地址 ------> http://www.huacolor.com/soft/69625.html
这个东西可以将两个文本文档进行比较。
将你的所有输出保存在一个txt文件中 (fprintf总会吧)
然后复制下面我AC的代码,也保存在一个文件中,直接相比较,就能找到问题在哪。
多试几组数据,随便输入,找个几次一定可以找到问题所在。
关于其中的几点要说两句。
第一,在升旗的问题处理上。注意平局的话也不算连胜。
第二,武士应该是先获得司令部奖励的生命元,司令部再获得生命元,所以应该先保存起来,司令部能在这一轮中得到多少生命元,执行奖励,司令部的生命元再加。
第三,关于行军问题,这就和数组中的每个元素向前一个或者向后一个类似。
第四,在估计是否使用bomb时一定要注意,一击能否杀死敌人,或者敌人是否是ninjia不会反击的!
第五,也是最麻烦的一点,就是射箭问题。因为射箭后杀死敌人,如果其城市有己方,仍算己方胜利,武士仍会欢呼等。所以我的方法是,如果射箭杀死敌人的话不立刻将敌人的指针变为NULL,而是先将其hp变为0,即“假死状态”,然后再在beat函数前加一个判断。要注意双方都被射死的情况!
大意就这么多。衷心希望每个人都能尽快AC。
下面是我的AC代码,没加任何注释。不过函数以及变量的命名应该还是蛮清晰的。
516K,30MS,14757B
#include
#include
#include
using namespace std;
const int DRAGON=0,NINJIA=1,ICEMAN=2,LION=3,WOLF=4;
const int now_order[2][5]={{2,3,4,1,0},{3,0,1,2,4}};
const char* s[2]={"red","blue"};
const char* ss[5]={"dragon","ninja","iceman","lion","wolf"};
const char* sss[3]={"sword","bomb","arrow"};
int need[5],order[2],number[2],_attack[5],worriors_temp[2],now_time,city_sum,total[2],arrow_attack,loyalty_minus;
bool head_num[2],game_over,last_color[2];
class sword
{
private:
int force;
public:
sword(int x):force(x) {}
void used() {force=force*0.8;}
bool is_deserted() {return (force==0);}
int get_force() {return force;}
};
class arrow
{
private:
int used_times;
int force;
public:
arrow(int x,int y):used_times(x),force(y) {}
void used() {used_times--;}
bool is_deserted() {return (used_times==0);}
int get_force() {return force;}
int get_used_time() {return used_times;}
};
class worriors
{
public:
worriors(int,int,int);
~worriors()
{
if (_sword!=NULL) delete _sword;
if (_arrow!=NULL) delete _arrow;
}
void get_hp(int a) {hp+=a;}
virtual void happy(int) {}
virtual void change_morale(int) {}
virtual bool will_escape() {return false;}
virtual void minus_loyalty() {}
friend class city;
protected:
int type;
int id;
int hp;
int color;
int attack;
sword* _sword;
arrow* _arrow;
bool has_bomb;
};
class dragon: public worriors
{
private:
double morale;
public:
dragon(int _color,int _id,int _type):worriors(_color,_id,_type)
{
morale=(double)total[_color]/(double)need[0];
printf("Its morale is %.2lf\n",morale);
}
void happy(int _id)
{
if (morale>0.8)
printf("%.3d:40 %s dragon %d yelled in city %d\n",now_time,s[color],id,_id);
}
void change_morale(int a) {morale+=((a==1)?0.2:-0.2);}
};
class lion: public worriors
{
private:
int loyalty;
public:
lion(int _color,int _id,int _type):worriors(_color,_id,_type)
{
loyalty=total[_color];
printf("Its loyalty is %d\n",loyalty);
}
bool will_escape() {return (loyalty<=0);}
void minus_loyalty() {loyalty-=loyalty_minus;}
};
class city
{
private:
int id;
int color;
int hp;
int last_beat_win;
int just_beat_win;
public:
worriors* data[2];
~city()
{
for (int i=0;i<=1;i++)
if (data[i]!=NULL)
delete data[i];
}
void creat(int);
void input_hp() {hp+=10;};
void output_hp();
void beat_win(int,int,int);
void beat();
void draw(int);
void go(city*,int);
bool reach_headquater(int);
void print_last_go();
void escape(int);
void use_bomb();
void tell_weapon(int);
void shoot_arrow(city*,int);
int get_attack(int);
int get_just_beat_win() {return just_beat_win;}
void bang(int);
} citys[22];
worriors::worriors(int _color,int _id,int _type)
{
printf("%.3d:00 %s %s %d born\n",now_time,s[_color],ss[_type],_id);
total[_color]-=need[_type];
id=_id;
color=_color;
type=_type;
hp=need[_type];
attack=_attack[_type];
_sword=NULL;
has_bomb=false;
_arrow=NULL;
switch(_type)
{
case DRAGON:case ICEMAN:
switch (id%3)
{
case 0:
if ((int)(attack*0.2)!=0)
_sword=new sword(attack*0.2);
break;
case 1:
has_bomb=true;
break;
default:
_arrow=new arrow(3,arrow_attack);
}
break;
case NINJIA:
switch(id%3)
{
case 0:
if ((int)(attack*0.2)!=0)
_sword=new sword(attack*0.2);
has_bomb=true;
break;
case 1:
has_bomb=true;
_arrow=new arrow(3,arrow_attack);
break;
default:
_arrow=new arrow(3,arrow_attack);
if ((int)(attack*0.2)!=0)
_sword=new sword(attack*0.2);
}
break;
default:;
}
}
void city::creat(int _id)
{
last_beat_win=just_beat_win=color=-1;
id=_id;
hp=0;
data[0]=data[1]=NULL;
}
void city::beat_win(int _color,int left_hp,int y)
{
if (data[_color]->type==WOLF)
{
if (data[_color]->_sword==NULL && data[1-_color]->_sword!=NULL)
data[_color]->_sword=new sword(data[1-_color]->_sword->get_force());
if (!data[_color]->has_bomb && data[1-_color]->has_bomb)
data[_color]->has_bomb=true;
if (data[_color]->_arrow==NULL && data[1-_color]->_arrow!=NULL)
data[_color]->_arrow=new arrow(data[1-_color]->_arrow->get_used_time(),data[1-_color]->_arrow->get_force());
}
delete data[1-_color];
data[1-_color]=NULL;
if (y==1)
{
data[_color]->change_morale(1);
data[_color]->happy(id);
}
data[_color]->hp+=left_hp;
printf("%.3d:40 %s %s %d earned %d elements for his headquarter\n",now_time,
s[_color],ss[data[_color]->type],data[_color]->id,hp);
worriors_temp[_color]+=hp;
hp=0;
just_beat_win=_color;
if (color!=_color && last_beat_win==_color)
{
color=_color;
printf("%.3d:40 %s flag raised in city %d\n",now_time,s[_color],id);
}
last_beat_win=_color;
}
void city::output_hp()
{
int turn=-1;
if (data[0]!=NULL && data[1]==NULL) turn=0;
if (data[1]!=NULL && data[0]==NULL) turn=1;
if (turn!=-1)
{
printf("%.3d:30 %s %s %d earned %d elements for his headquarter\n",now_time,s[turn],ss[data[turn]->type],data[turn]->id,hp);
total[turn]+=hp;
hp=0;
}
}
void city::beat()
{
int turn=1,left_hp=0,add_attack;
just_beat_win=-1;
if (data[0]==NULL)
{
if (data[1]!=NULL && data[1]->hp==0)
{
delete data[1];
data[1]=NULL;
}
return;
}
if (data[1]==NULL)
{
if (data[0]->hp==0)
{
delete data[0];
data[0]=NULL;
}
return;
}
if (color==0 || (color==-1 && id%2==1)) turn=0;
if (data[turn]->hp==0 && data[1-turn]->hp==0)
{
delete data[0];
delete data[1];
data[0]=data[1]=NULL;
return;
}
if (data[turn]->hp==0)
{
beat_win(1-turn,0,0);
return;
}
if (data[1-turn]->hp==0)
{
beat_win(turn,0,1);
return;
}
printf("%.3d:40 %s %s %d ",now_time,s[turn],ss[data[turn]->type],data[turn]->id);
printf("attacked %s %s %d in city %d with %d elements and force %d\n",s[1-turn],ss[data[1-turn]->type],data[1-turn]->id,id,data[turn]->hp,data[turn]->attack);
if (data[1-turn]->type==LION)
left_hp=data[1-turn]->hp;
add_attack=get_attack(turn);
data[1-turn]->hp-=data[turn]->attack+add_attack;
if (data[1-turn]->hp<=0)
{
printf("%.3d:40 %s %s %d was killed in city %d\n",now_time,s[data[1-turn]->color],ss[data[1-turn]->type],data[1-turn]->id,id);
beat_win(turn,left_hp,1);
return;
}
if (data[1-turn]->type!=NINJIA)
{
add_attack=get_attack(1-turn);
printf("%.3d:40 %s %s %d fought back against %s %s %d in city %d\n",now_time,s[1-turn],
ss[data[1-turn]->type],data[1-turn]->id,s[turn],ss[data[turn]->type],data[turn]->id,id);
if (data[turn]->type==LION)
left_hp=data[turn]->hp;
else left_hp=0;
data[turn]->hp-=data[1-turn]->attack/2+add_attack;
if (data[turn]->hp<=0)
{
printf("%.3d:40 %s %s %d was killed in city %d\n",now_time,s[data[turn]->color],ss[data[turn]->type],
data[turn]->id,id);
beat_win(1-turn,left_hp,0);
return;
}
}
draw(turn);
}
int city::get_attack(int _color)
{
int add_attack=0;
if (data[_color]->_sword!=NULL)
{
add_attack=data[_color]->_sword->get_force();
data[_color]->_sword->used();
if (data[_color]->_sword->is_deserted())
{
delete data[_color]->_sword;
data[_color]->_sword=NULL;
}
}
return add_attack;
}
void city::draw(int turn)
{
data[0]->minus_loyalty();
data[1]->minus_loyalty();
data[turn]->change_morale(-1);
data[turn]->happy(id);
last_beat_win=-1;
}
void city::go(city* next,int _color)
{
data[_color]=next->data[_color];
if (data[_color]!=NULL && data[_color]->type==ICEMAN)
{
if ((_color==0 && id%2==0) || (_color==1 && (city_sum-id)%2==1))
{
data[_color]->hp-=9;
if (data[_color]->hp<=0) data[_color]->hp=1;
data[_color]->attack+=20;
}
}
}
bool city::reach_headquater(int _color)
{
if (!last_color[_color]) return false;
printf("%.3d:10 %s %s %d reached %s headquarter with %d elements and force %d\n",now_time,
s[_color],ss[data[_color]->type],data[_color]->id,s[1-_color],data[_color]->hp,data[_color]->attack);
if (head_num[_color]) return true;
head_num[_color]=true;
return false;
}
void city::print_last_go()
{
for (int i=0;i<=1;i++)
if (data[i]!=NULL)
printf("%.3d:10 %s %s %d marched to city %d with %d elements and force %d\n",now_time,
s[i],ss[data[i]->type],data[i]->id,id,data[i]->hp,data[i]->attack);
}
void city::escape(int i)
{
if (data[i]!=NULL && data[i]->will_escape())
{
printf("%.3d:05 %s lion %d ran away\n",now_time,s[i],data[i]->id);
delete data[i];
data[i]=NULL;
}
}
void city::use_bomb()
{
int turn=1;
if (data[0]==NULL || data[1]==NULL || data[0]->hp==0 || data[1]->hp==0)
return;
if (color==0 || (color==-1 && id%2==1)) turn=0;
int add_force=0;
if (data[turn]->_sword!=NULL)
add_force=data[turn]->_sword->get_force();
if (data[1-turn]->hp<=data[turn]->attack+add_force)
{
if (data[1-turn]->has_bomb)
bang(1-turn);
return;
}
if (data[1-turn]->type==NINJIA)
return;
add_force=0;
if (data[1-turn]->_sword!=NULL)
add_force=data[1-turn]->_sword->get_force();
if (data[turn]->hp<=data[1-turn]->attack/2+add_force && data[turn]->has_bomb)
bang(turn);
}
void city::bang(int turn)
{
printf("%.3d:38 %s %s %d used a bomb and killed %s %s %d\n",now_time,s[turn],
ss[data[turn]->type],data[turn]->id,s[1-turn],ss[data[1-turn]->type],data[1-turn]->id);
delete data[0];
delete data[1];
data[0]=data[1]=NULL;
}
void city::tell_weapon(int _color)
{
bool e=false;
if (data[_color]==NULL) return;
printf("%.3d:55 %s %s %d has ",now_time,s[_color],ss[data[_color]->type],data[_color]->id);
if (data[_color]->_arrow!=NULL)
{
printf("arrow(%d)",data[_color]->_arrow->get_used_time());
e=true;
}
if (data[_color]->has_bomb)
{
if (e) printf(",");
printf("bomb");
e=true;
}
if (data[_color]->_sword!=NULL)
{
if (e) printf(",");
printf("sword(%d)",data[_color]->_sword->get_force());
e=true;
}
if (!e) printf("no weapon");
printf("\n");
}
void city::shoot_arrow(city* next,int _color)
{
if (data[_color]==NULL) return;
if (data[_color]->_arrow!=NULL && next->data[1-_color]!=NULL)
{
printf("%.3d:35 %s %s %d shot",now_time,s[_color],ss[data[_color]->type],data[_color]->id);
next->data[1-_color]->hp-=data[_color]->_arrow->get_force();
data[_color]->_arrow->used();
if (data[_color]->_arrow->is_deserted())
{
delete data[_color]->_arrow;
data[_color]->_arrow=NULL;
}
if (next->data[1-_color]->hp<=0)
{
next->data[1-_color]->hp=0;
printf(" and killed %s %s %d",s[1-_color],ss[next->data[1-_color]->type],next->data[1-_color]->id);
}
printf("\n");
}
}
void creat()
{
for (int i=0;i<=1;i++)
{
if (total[i]>=need[now_order[i][order[i]]])
{
worriors* temp;
number[i]++;
switch (now_order[i][order[i]])
{
case 0:
temp=new dragon(i,number[i],now_order[i][order[i]]);
break;
case 3:
temp=new lion(i,number[i],now_order[i][order[i]]);
break;
default:
temp=new worriors(i,number[i],now_order[i][order[i]]);
}
citys[((i==0)?0:(city_sum+1))].data[i]=temp;
order[i]=(order[i]+1)%5;
}
}
}
void go_ahead()
{
last_color[0]=last_color[1]=false;
if (citys[city_sum].data[0]!=NULL)
{
citys[city_sum+1].go(&citys[city_sum],0);
last_color[0]=true;
}
for (int i=city_sum;i>=1;i--)
citys[i].go(&citys[i-1],0);
if (citys[1].data[1]!=NULL)
{
citys[0].go(&citys[1],1);
last_color[1]=true;
}
for (int i=1;i<=city_sum;i++)
citys[i].go(&citys[i+1],1);
citys[0].data[0]=citys[city_sum+1].data[1]=NULL;
if (citys[0].reach_headquater(1))
{
printf("%.3d:10 red headquarter was taken\n",now_time);
game_over=true;
}
for (int i=1;i<=city_sum;i++)
citys[i].print_last_go();
if (citys[city_sum+1].reach_headquater(0))
{
printf("%.3d:10 blue headquarter was taken\n",now_time);
game_over=true;
}
}
void pride()
{
for (int i=1;i<=city_sum;i++)
{
if (total[1]<8) break;
if (citys[i].get_just_beat_win()==1)
{
citys[i].data[1]->get_hp(8);
total[1]-=8;
}
}
for (int i=city_sum;i>=1;i--)
{
if (total[0]<8) break;
if (citys[i].get_just_beat_win()==0)
{
citys[i].data[0]->get_hp(8);
total[0]-=8;
}
}
for (int i=0;i<=1;i++)
{
total[i]+=worriors_temp[i];
worriors_temp[i]=0;
}
}
int main()
{
//freopen("E:/cpp/1.txt","r",stdin);
//freopen("1.txt","w",stdout);
int times,input,total_time,already_time;
scanf("%d",×);
for (int t=1;t<=times;t++)
{
scanf("%d %d %d %d %d",&input,&city_sum,&arrow_attack,&loyalty_minus,&total_time);
total[0]=total[1]=input;
already_time=0;
game_over=false;
now_time=-1;
number[0]=number[1]=0;
order[0]=order[1]=0;
head_num[0]=head_num[1]=false;
for (int i=0;i<=4;i++)
scanf("%d",&need[i]);
for (int i=0;i<=4;i++)
scanf("%d",&_attack[i]);
printf("Case %d:\n",t);
for (int i=0;i<=city_sum+1;i++)
citys[i].creat(i);
while (1)
{
now_time++;
creat();
already_time+=5;
if (already_time>total_time) break;
citys[0].escape(0);
for (int i=1;i<=city_sum;i++)
for (int j=0;j<=1;j++)
citys[i].escape(j);
citys[city_sum+1].escape(1);
already_time+=5;
if (already_time>total_time) break;
go_ahead();
for (int i=1;i<=city_sum;i++)
citys[i].input_hp();
already_time+=20;
if (game_over || already_time>total_time) break;
for (int i=1;i<=city_sum;i++)
citys[i].output_hp();
already_time+=5;
if (already_time>total_time) break;
citys[1].shoot_arrow(&citys[2],0);
for (int i=2;i<=city_sum-1;i++)
{
citys[i].shoot_arrow(&citys[i+1],0);
citys[i].shoot_arrow(&citys[i-1],1);
}
citys[city_sum].shoot_arrow(&citys[city_sum-1],1);
already_time+=3;
if (already_time>total_time) break;
for (int i=1;i<=city_sum;i++)
citys[i].use_bomb();
already_time+=2;
if (already_time>total_time) break;
for (int i=1;i<=city_sum;i++)
citys[i].beat();
pride();
already_time+=10;
if (already_time>total_time) break;
for (int i=0;i<=1;i++)
printf("%.3d:50 %d elements in %s headquarter\n",now_time,total[i],s[i]);
already_time+=5;
if (already_time>total_time) break;
for (int j=0;j<=1;j++)
for (int i=0;i<=city_sum+1;i++)
citys[i].tell_weapon(j);
already_time+=5;
if (already_time>total_time) break;
}
}
//fclose(stdin);
//fclose(stdout);
//system("pause");
return 0;
}