模拟
宏定义预处理器,实现简化版预处理器,不包含函数,字符ASCII码范围32~126.
namespace JRC{
string solve(string s){
string re="";
for(int i=0,j=0;i<s.size();i+=j){/*每次往后跳一个字符串的长度*/
for(j=0;i+j<s.size()&&isalnum(s[i+j])||s[i+j]=='_';j++);
if(j){
string tmp=s.substr(i,j);/*截取当前串*/
if(def.count(tmp)&&!def[tmp].second){/*被定义且未处于展开状态*/
def[tmp].second=1;/*开始展开*/
re+=solve(def[tmp].first);/*递归展开*/
def[tmp].second=0;/*展开结束*/
}
else re+=tmp;
}
else re+=s[i++];
}
return re;
}
inline void main(){
cin>>n;
for(int i=0;i<=n;i++)getline(cin,s[i]);
for(int i=1;i<=n;i++){
if(s[i][0]=='#'){
if(s[i][1]=='d'){
int pos=s[i].find_first_of(' ',8);/*找到第二个空格的位置*/
string name=s[i].substr(8,pos-8)/*截取定义名*/,to=s[i].substr(pos+1);/*剩下的全部是转换成的文本*/
def[name]={to,0};
}
else def.erase(s[i].substr(7));
cout<<'\n';
}
else cout<<solve(s[i])<<'\n';
}
}
}
儒略日。数学找规律。
// 2299160:
// int ans=0;
// for(int i=-4712;i<1582;i++)ans+=365+(i%4==0);
// for(int i=1;i<=9;i++){
// if(i==4||i==6||i==9||i==11)ans+=30;
// else if(i==2)ans+=28;
// else ans+=31;
// }
// ans+=4
#define int long long
const int N=146097;/*格里高利历一年的天数*/
int y[N],m[N],d[N];
namespace JRC{
inline int mod(int y,int m){/*格里高利历在y年m月对应的天数*/
if(m==2)return(y%400==0||(y%4==0&&y%100))?29:28;
return (m==4||m==6||m==9||m==11)?30:31;
}
inline void main(){
m[0]=d[0]=1;
for(int i=1;i<N;i++){
d[i]=d[i-1]+1;
m[i]=m[i-1];
y[i]=y[i-1];
if(d[i]>mod(y[i],m[i]))d[i]=1,m[i]++;
if(m[i]>12)m[i]=1,y[i]++;
}
int q;
cin>>q;
while(q--){
int n,t;
cin>>n;
if(n>2299160){/*公元1582年10月4日是第2299160天,之后是格里高利历*/
n-=2159351;/*第2159351天对应公元1199年12月25日*/
t=n/N*400+1200;
n%=N;
}
else{/*第一天即公元前4713年1月2日*/
t=n/1461*4-4712;
n%=1461;/*儒略历4年的天数*/
}
if(t+y[n]>0)cout<<d[n]<<' '<<m[n]<<' '<<t+y[n]<<'\n';
else cout<<d[n]<<' '<<m[n]<<' '<<1-t-y[n]<<" BC\n";
}
}
}
斗地主,3<4<5<6<7<8<9<10<J<Q<K<A<2<小王<大王,分别最少需要多少次出牌可以将它们打光,出牌包括双王,四张为炸弹,单牌,对牌,三牌,三带一,三带一对,单顺子,双顺子,三顺子,四带两张单牌,四带两对牌,其中顺子不包含2和大小王。优先顺子,之后几带几,最后是三牌,搜索加模拟。
namespace JSY{
void dfs(int x){
if(x>=ans)return;/*只有顺子不带2和王*/
for(int i=3,k=0;i<=14;i++){
if(cnt[i]<1){/*单顺子*/
k=0;
continue;
}
k++;
if(k<5)continue;
for(int j=i;j>=i-k+1;j--)cnt[j]--;
dfs(x+1);
for(int j=i;j>=i-k+1;j--)cnt[j]++;
}
for(int i=3,k=0;i<=14;i++){
if(cnt[i]<2){/*双顺子*/
k=0;
continue;
}
k++;
if(k<3)continue;
for(int j=i;j>=i-k+1;j--)cnt[j]-=2;
dfs(x+1);
for(int j=i;j>=i-k+1;j--)cnt[j]+=2;
}
for(int i=3,k=0;i<=14;i++){
if(cnt[i]<3){/*三顺子*/
k=0;
continue;
}
k++;
if(k<2)continue;
for(int j=i;j>=i-k+1;j--)cnt[j]-=3;
dfs(x+1);
for(int j=i;j>=i-k+1;j--)cnt[j]+=3;
}
for(int i=2;i<=14;i++){
if(cnt[i]<3)continue;/*判断可以带牌*/
if(cnt[i]<4){/*用三张i去带别人*/
cnt[i]-=3;
for(int j=2;j<=15;j++){/*判断三带一*/
if(i==j||cnt[j]<1)continue;
cnt[j]--;/*j被带走了一张*/
dfs(x+1);
cnt[j]++;/*回溯*/
if(cnt[j]<2)continue;/*判断可以三带一对*/
cnt[j]-=2;/*j被带走了一对*/
dfs(x+1);
cnt[j]+=2;/*回溯*/
}
cnt[i]+=3;
}
else{
cnt[i]-=3;/*优先三张i去带别人*/
for(int j=2;j<=15;j++){
if(i==j||cnt[j]<1)continue;
cnt[j]--;
dfs(x+1);
cnt[j]++;
if(cnt[j]<2)continue;
cnt[j]-=2;
dfs(x+1);
cnt[j]+=2;
}
cnt[i]+=3;
cnt[i]-=4;/*四张i去带别人,四带两单或两对*/
for(int j=2;j<=15;j++){
if(i==j||cnt[j]<1)continue;
cnt[j]--;/*找到一单*/
for(int k=j+1;k<=15;k++){
if(i==k||cnt[k]<1)continue;
cnt[k]--;/*找到二单*/
dfs(x+1);
cnt[k]++;
}
cnt[j]++;
}
for(int j=2;j<=14;j++){
if(i==j||cnt[j]<2)continue;
cnt[j]-=2;/*找到一对*/
for(int k=j+1;k<=14;k++){
if(j==k||i==k||cnt[k]<2)continue;
cnt[k]-=2;/*找到二对*/
dfs(x+1);
cnt[k]+=2;
}
cnt[j]+=2;
}
cnt[i]+=4;
}
}
for(int i=2;i<=15;i++)if(cnt[i])x++;
ans=min(ans,x);
}
inline void main(){
int t;cin>>t>>n;
while(t--){
ans=66;
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;i++){
int x,y;
cin>>x>>y;
switch(x){
case 1:cnt[14]++;break;
case 0:cnt[15]++;break;
default:cnt[x]++;break;
}
}
dfs(0);
cout<<ans<<'\n';
}
}
}
猪国杀。无懈可击要递归处理,对于每张牌如果能出,要先删掉再进行相应的操作。
#include<cstdio>
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
const int N=666;
int n;
int m;
int maxhp=4;//血量上限
int running=1;//游戏未结束
int tot;//存活者数量
int cnt;//反猪数量
struct Player{
string identity;//身份
int hp=maxhp;//血量
int nxt=0;//下一个人
int pre=0;//上一个人
bool showidentity=0;//跳身份
bool similar=0;//类反猪
bool equip=0;//装备
bool dead=0;//死亡
vector<string>card;//手牌
inline void clear(){
identity.clear();
card.clear();
hp=maxhp;
nxt=0;
pre=0;
showidentity=0;
similar=0;
dead=0;
}
inline void get(string s){//增加手牌
card.push_back(s);
}
inline bool have(string s){//是否有特定手牌
for(auto it=card.begin();it!=card.end();it++){
if(*it==s){
return 1;
}
}
return 0;
}
inline void erase(string s){//弃置特定手牌
for(auto it=card.begin();it!=card.end();it++){
if(*it==s){
card.erase(it);
return;
}
}
}
inline vector<string>::iterator erase(vector<string>::iterator it){
it=card.erase(it);
return --it;
}
inline void show(){
cout<<"身份:"<<identity<<",血量:"<<hp<<",跳:"<<showidentity<<",类:"<<similar<<",装备:"<<equip<<",死亡:"<<dead<<'\n';
cout<<"手牌:";
for(auto x:card)cout<<x<<' ';
cout<<'\n';
}
}player[N];
struct Card{
queue<string>card;
inline void clear(){
while(!card.empty()){
card.pop();
}
}
inline void push(string s){//牌堆增加牌
card.push(s);
}
inline string get(){//从牌堆取牌
if(card.size()==1){
return card.front();
}
string s=card.front();
card.pop();
return s;
}
}card;
inline void showidentity(int id){
if(player[id].identity=="MP"){
cout<<"主猪";
}
else if(player[id].identity=="ZP"){
cout<<"忠猪";
}
else if(player[id].identity=="FP"){
cout<<"反猪";
}
}
inline void showcard(string s){
if(s=="P"){
cout<<"【桃】";
}
else if(s=="K"){
cout<<"【杀】";
}
else if(s=="D"){
cout<<"【闪】";
}
else if(s=="F"){
cout<<"【决斗】";
}
else if(s=="N"){
cout<<"【南猪入侵】";
}
else if(s=="W"){
cout<<"【万箭齐发】";
}
else if(s=="J"){
cout<<"【无懈可击】";
}
else if(s=="Z"){
cout<<"【猪哥连弩】";
}
}
inline void use(int id,string s,int to=0){
if(!to){
showidentity(id);
cout<<id<<"使用了";
showcard(s);
cout<<'\n';
}
else{
showidentity(id);
cout<<id<<"对";
showidentity(to);
cout<<to<<"使用了";
showcard(s);
cout<<'\n';
}
}
inline void getcard(int id,int n=2){//id取n张牌
for(int i=1;i<=n;i++){
player[id].get(card.get());
}
}
inline void init(){
cin>>n>>m;
tot=n;
card.clear();
for(int i=1;i<=n;i++){
player[i].clear();
player[i].nxt=i+1;
player[i].pre=i-1;
string s;
cin>>s;
player[i].identity=s;
if(s=="FP"){
cnt++;
}
for(int j=1;j<=4;j++){
cin>>s;
player[i].get(s);
}
}
player[1].showidentity=1;
player[1].pre=n;
player[n].nxt=1;
running=1;
for(int i=1;i<=m;i++){
string s;
cin>>s;
card.push(s);
}
}
inline bool same(int x,int y){//同一阵营
if(player[x].identity==player[y].identity){//相同类型
return 1;
}
if(player[x].identity=="MP"&&player[y].identity=="ZP"){//主猪与忠猪
return 1;
}
if(player[x].identity=="ZP"&&player[y].identity=="MP"){//忠猪与主猪
return 1;
}
return 0;
}
inline bool bad(int x,int y){//表敌意
if(!player[y].showidentity){//未表露身份
if(player[x].identity=="MP"&&player[y].similar){//主猪对类反猪
return 1;
}
return 0;//无法表露敌意
}
return !same(x,y);
}
inline int bad(int id){
if(player[id].identity=="FP"){//反猪对主猪表敌意
return 1;
}
int to=player[id].nxt;
while(id!=to){
if(bad(id,to)){
return to;
}
to=player[to].nxt;
}
return 0;
}
inline bool good(int x,int y){
if(!player[y].showidentity){//不会对未表露身份的角色献殷勤
return 0;
}
return same(x,y);
}
inline void Peach(int id){//使用【桃】
// use(id,"P");
player[id].hp++;
}
inline void dead(int from,int to){
if(player[to].have("P")){//濒死者用【桃】回血
Peach(to);
player[to].erase("P");
return;
}
player[to].dead=1;
tot--;
if(player[to].identity=="MP"){
running=0;//主猪死亡,游戏结束
return;
}
else if(player[to].identity=="FP"){
cnt--;
if(!cnt){
running=0;
return;
}
}
player[player[to].pre].nxt=player[to].nxt;
player[player[to].nxt].pre=player[to].pre;
if(player[to].identity=="FP"){//杀死反猪摸三张
getcard(from,3);
}
else if(player[from].identity=="MP"&&player[to].identity=="ZP"){//主猪杀死忠猪
player[from].card.clear();//弃置手牌
player[from].equip=0;//弃置装备
}
}
inline void hurt(int from,int to){
player[to].hp--;
if(player[to].identity=="MP"){//攻击主猪者被视为类反猪
player[from].similar=1;
}
if(!player[to].hp)dead(from,to);
}
inline void Equipment(int id){//使用【猪哥连弩】
player[id].equip=1;
}
inline void Kill(int from,int to){//使用【杀】
player[from].showidentity=1;//对敌方表敌意,那么自己表露了身份
if(player[to].have("D")){//敌方有【闪】
// use(to,"D");
player[to].erase("D");
}
else{
hurt(from,to);//造成伤害
}
}
bool Flawless(int from,int to,int op){//【无懈可击】递归
int k=tot;
while(k--){
if(player[to].have("J")){
if(op&&good(to,from)){//op=1表示需要对from献殷勤,from是收到伤害的一方,需要无懈可击的支援
// use(to,"J",from);
player[to].showidentity=1;
player[to].erase("J");
return !Flawless(from,player[to].nxt,op^1);//需要对from表敌意的人表敌意失败,那么自己便成功了
}
else if(!op&&bad(to,from)){//op=0表示需要对from表敌意
// use(to,"J",from);
player[to].showidentity=1;
player[to].erase("J");
return !Flawless(from,player[to].nxt,op^1);
}
}
to=player[to].nxt;
}
return 0;
}
inline void Duel(int from,int to){//【决斗】
player[from].showidentity=1;
if(Flawless(to,from,1))return;
if(player[from].identity=="MP"&&player[to].identity=="ZP"){//忠猪不对主猪的决斗出杀
hurt(from,to);
return;
}
while(1){
if(player[to].have("K")){
// use(to,"K");
player[to].erase("K");
}
else{
hurt(from,to);
break;
}
if(player[from].have("K")){
// use(to,"K");
player[from].erase("K");
}
else{
hurt(to,from);
break;
}
}
}
inline void BarbarianBreakout(int id){//【南猪入侵】
int to=player[id].nxt;
while(id!=to&&running){
if(Flawless(to,id,1)){
to=player[to].nxt;
continue;
}
if(player[to].have("K")){
player[to].erase("K");
to=player[to].nxt;
continue;
}
hurt(id,to);
to=player[to].nxt;
}
}
inline void ThousandSpear(int id){//【万箭齐发】
int to=player[id].nxt;
while(id!=to&&running){
if(Flawless(to,id,1)){
to=player[to].nxt;
continue;
}
if(player[to].have("D")){
player[to].erase("D");
to=player[to].nxt;
continue;
}
hurt(id,to);
to=player[to].nxt;
}
}
inline void play(){
int id=1;//本回合玩家编号
bool usekill=0;//是否使用过杀
bool usecard=0;//是否出过牌
while(running){
getcard(id,2);
usekill=0;
while(!player[id].dead&&running){
usecard=0;
for(auto it=player[id].card.begin();it!=player[id].card.end();it++){
if(player[id].dead||!running)break;
if(*it=="P"){
if(player[id].hp<maxhp){
usecard=1;
Peach(id);
player[id].erase(it);
}
}
else if(*it=="Z"){
usecard=1;
Equipment(id);
usekill=0;//可以再次使用杀
player[id].erase(it);
}
else if(*it=="K"){
if(usekill)continue;
if(bad(id,player[id].nxt)){
usecard=1;
if(!player[id].equip)usekill=1;
player[id].erase(it);
Kill(id,player[id].nxt);
}
}
else if(*it=="F"){
int to=bad(id);
if(!to)continue;
usecard=1;
player[id].erase(it);
Duel(id,to);
}
else if(*it=="N"){
usecard=1;
player[id].erase(it);
BarbarianBreakout(id);
}
else if(*it=="W"){
usecard=1;
player[id].erase(it);//顺序相关?
ThousandSpear(id);
}
if(usecard)break;
}
if(!usecard)break;
}
id=player[id].nxt;
}
}
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
init();
play();
if(!cnt){
cout<<"MP\n";
}
else{
cout<<"FP\n";
}
for(int i=1;i<=n;i++){
if(player[i].dead){
cout<<"DEAD\n";
}
else{
for(auto x:player[i].card){
cout<<x<<' ';
}
cout<<'\n';
}
}
return 0;
}
压行版本。
#include<bits/stdc++.h>
using namespace std;
const int N=666;
int n,m,maxhp=4,tot,cnt;bool running;
struct Player{
string identity;int hp=maxhp,nxt,pre,showidentity,similar,equip,dead;vector<string>card;
inline bool operator==(const Player&x){return (identity==x.identity)||(identity=="MP"&&x.identity=="ZP")||(identity=="ZP"&&x.identity=="MP");}
inline bool operator!=(const Player&x){return ((*this)==x)==false;}
inline void operator+=(string s){card.push_back(s);}
inline void operator~(){identity.clear();card.clear();hp=maxhp;nxt=pre=showidentity=similar=dead=false;}
inline bool operator-(string s){for(auto x:card)if(x==s)return true;return false;}
inline void operator-=(string s){for(auto it=card.begin();it!=card.end();it++)if(*it==s)return card.erase(it),void();}
}player[N];
struct Card{
queue<string>card;
inline void operator~(){while(!card.empty())card.pop();}
inline void operator+=(string s){card.push(s);}
inline string operator--(){if(card.size()==1)return card.front();string s=card.front();card.pop();return s;}
}card;
inline void getcard(int x,int n){while(n--)player[x]+=--card;}
inline bool good(int x,int y){return player[y].showidentity?player[x]==player[y]:false;}
inline bool bad(int x,int y){return player[y].showidentity?(player[x]!=player[y]):(player[x].identity=="MP"&&player[y].similar==true);}
inline void nxt(int&x){x=player[x].nxt;}
inline int findgoal(int x){if(player[x].identity=="FP")return 1;int y=player[x].nxt;while(x!=y){if(bad(x,y))return y;nxt(y);}return 0;}
inline void Peach(int x){player[x].hp++;}
inline void dead(int x,int y){
if(player[y]-"P")return Peach(y),player[y]-="P",void();
player[y].dead=true,tot--;
if(player[y].identity=="MP"||(player[y].identity=="FP"&&--cnt==false))return running=false,void();
player[player[y].pre].nxt=player[y].nxt,player[player[y].nxt].pre=player[y].pre,player[y].identity=="FP"?(getcard(x,3),0):((player[x].identity=="MP"&&player[y].identity=="ZP")?player[x].card.clear(),player[x].equip=false:0);
}
inline void hurt(int x,int y){player[y].hp--,player[x].similar=player[y].identity=="MP",(player[y].hp==false)?dead(x,y),0:0;}
inline void Equipment(int x){player[x].equip=true;}
inline void Kill(int x,int y){player[x].showidentity=true,player[y]-"D"?player[y]-="D":hurt(x,y);}
bool Flawless(int x,int y,bool f){for(int k=tot;k;k--,nxt(y))if(player[y]-"J"==true&&((f==true&&good(y,x))||(f==false&&bad(y,x))))return player[y].showidentity=true,player[y]-="J",Flawless(x,player[y].nxt,f^1)==false;return false;}
inline void Duel(int x,int y){
player[x].showidentity=true;
if(Flawless(y,x,true)==true)return;
if(player[x].identity=="MP"&&player[y].identity=="ZP")return hurt(x,y),void();
while(true){
if(player[y]-"K")player[y]-="K";
else{hurt(x,y);break;}
if(player[x]-"K")player[x]-="K";
else{hurt(y,x);break;}
}
}
inline void BarbarianBreakout(int x){for(int y=player[x].nxt;x!=y&&running==true;nxt(y))(Flawless(y,x,true)||(player[y]-"K"&&(player[y]-="K",1)))?1:(hurt(x,y),1);}
inline void ThousandSpear(int x){for(int y=player[x].nxt;x!=y&&running==true;nxt(y))(Flawless(y,x,true)||(player[y]-"D"&&(player[y]-="D",1)))?1:(hurt(x,y),1);}
inline void init(){
cin>>n>>m;tot=n;~card;string s;
for(int i=1;i<=n;i++){
~player[i];player[i].nxt=i+1,player[i].pre=i-1;
cin>>s;cnt+=s=="FP";player[i].identity=s;
for(int j=1;j<=4;j++)cin>>s,player[i]+=s;
}
player[1].pre=n,player[n].nxt=1,player[1].showidentity=true;
for(int i=1;i<=m;i++)cin>>s,card+=s;
running=true;
}
inline void play(){
int id=1,y;
while(running){
getcard(id,2);
bool usekill=false;
while(player[id].dead==false&&running){
bool usecard=false;
for(auto x:player[id].card){
if(player[id].dead==true||running==false)break;
if(x=="P"&&player[id].hp<maxhp)player[id]-="P",usecard=true,Peach(id);
else if(x=="Z")player[id]-="Z",usecard=true,usekill=false,Equipment(id);
else if(x=="K"&&usekill==false&&bad(id,player[id].nxt)!=false)player[id]-="K",usecard=true,usekill=player[id].equip^1,Kill(id,player[id].nxt);
else if(x=="F"&&(y=findgoal(id))!=false)player[id]-="F",usecard=true,Duel(id,y);
else if(x=="N")player[id]-="N",usecard=true,BarbarianBreakout(id);
else if(x=="W")player[id]-="W",usecard=true,ThousandSpear(id);
if(usecard==true)break;
}
if(usecard==false)break;
}
nxt(id);
}
}
inline void print(){
cout<<(cnt==false?"MP":"FP")<<'\n';
for(int i=1;i<=n;i++){
if(player[i].dead==true)cout<<"DEAD";
else for(auto x:player[i].card)cout<<x<<' ';
cout<<'\n';
}
}
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
init();
play();
print();
return 0;
}
杀蚂蚁。用STL的list维护当前存活的蚂蚁。
#include<cstdio>
#include<iostream>
#include<list>
#include<cmath>
using namespace std;
const int N=22;
const double eps=1e-8;
int n;
int m;
int num;//炮塔数量
int damage;//炮塔伤害
int radius;//炮塔攻击半径
int endtime;//模拟时间
int tim;//当前时间
int tot;//出生的蚂蚁总数
int livetot;//当前存活的蚂蚁数量
int dx[4]={0,1,0,-1};//方向数组
int dy[4]={1,0,-1,0};
bool cakefly=false;//蛋糕被抢
struct Map{
int information=0;//信息素含量
bool use=false;//是否被占用
}mp[N][N];
struct Ant{
int age=0;//年龄
int level=0;//等级
int hp=0;//血量
int maxhp=0;//血量上限
int x=0;//当前坐标
int y=0;
int px=0;//上一秒坐标
int py=0;
bool havecake=false;//背着蛋糕
};
list<Ant>ant;
struct Turret{
int x;
int y;
double radius=0;//最小攻击半径
bool havetarget=false;//是否有普通目标
bool caketarget=false;//是否有优先目标
list<Ant>::iterator target;//攻击目标
}turret[N];
inline void antborn(){//蚂蚁出生
if(livetot>5||mp[0][0].use==true){//不足六只且洞口没有蚂蚁才诞生
return;
}
tot++;
livetot++;
int level=(tot-1)/6+1;//等级
int hp=4*pow(1.1,level);//初始血量及上限
ant.push_back({0,level,hp,hp,0,0,0,0,false});
mp[0][0].use=true;//出生后的蚂蚁占用洞口
}
inline void release(){//释放信息素
for(auto x:ant){
if(x.havecake==true){
mp[x.x][x.y].information+=5;
}
else{
mp[x.x][x.y].information+=2;
}
}
}
inline bool check(int x,int y){
if(x<0||y<0||x>n||y>m||mp[x][y].use==true)return false;
return true;
}
inline void antmove(){//蚂蚁移动
for(auto&x:ant){
int maxinformation=0,pos=0,cnt=0;
for(int i=0;i<4;i++){
int tx=x.x+dx[i],ty=x.y+dy[i];
if(check(tx,ty)==true&&(x.px!=tx||x.py!=ty)){
if(mp[tx][ty].information>maxinformation){//优先信息素最多
maxinformation=mp[tx][ty].information;
pos=i;
cnt=1;
}
else if(mp[tx][ty].information==maxinformation){//多个相同信息素
pos=i;
cnt++;
}
}
}
if(cnt==0){//无路可走
x.px=x.x;
x.py=x.y;
continue;
}
if(cnt>1){
for(int i=0;i<4;i++){
int tx=x.x+dx[i],ty=x.y+dy[i];
if(check(tx,ty)&&(x.px!=tx||x.py!=ty)&&mp[tx][ty].information==maxinformation){//从东开始找到第一个
pos=i;
break;
}
}
}
if((x.age+1)%5==0){//需要逆时针转向
for(int i=0;i<4;i++){
pos--;
if(pos<0){
pos+=4;
}
int tx=x.x+dx[pos],ty=x.y+dy[pos];
if(check(tx,ty)&&(x.px!=tx||x.py!=ty)){//找到第一个可以走的方向
break;
}
}
}
x.px=x.x;
x.py=x.y;
x.x+=dx[pos];
x.y+=dy[pos];
mp[x.px][x.py].use=false;//清空之前标记
mp[x.x][x.y].use=true;//建立新标记
}
}
inline void checkcake(){//检查蛋糕是否被抢
if(cakefly==true){
return;
}
for(auto&x:ant){
if(x.x==n&&x.y==m){//蛋糕被抢
x.havecake=true;
cakefly=true;
x.hp=min(x.hp+(int)(1.0*x.maxhp/2.0),x.maxhp);//更新血量
break;
}
}
}
inline double getdis(double x,double y,double a,double b){
return sqrt((x-a)*(x-a)+(y-b)*(y-b));
}
struct Vector{
double x,y;
const double pi=acos(-1);
inline Vector(double a=0,double b=0){x=a,y=b;}
inline friend Vector operator+(const Vector&a,const Vector&b){return Vector(a.x+b.x,a.y+b.y);}
inline friend Vector operator-(const Vector&a,const Vector&b){return Vector(a.x-b.x,a.y-b.y);}
inline friend Vector operator*(const Vector&a,const double&b){return Vector(a.x*b,a.y*b);}
inline friend Vector operator/(const Vector&a,const double&b){return Vector(a.x/b,a.y/b);}
inline friend double operator&(const Vector&a,const Vector&b){return a.x*b.y-a.y*b.x;}//叉积
inline friend double operator|(const Vector&a,const Vector&b){return a.x*b.x+a.y*b.y;}//点积
inline double operator~()const{return sqrt(x*x+y*y);}//模长
inline double operator!()const{return atan2(y,x);}//弧度*180/pi=度数
inline double slope()const{return y/x;}
inline int doublepos(double x)const{return (fabs(x)<eps)?0:((x<0)?-1:1);}
inline Vector rotate(const double&a){return Vector(x*cos(a)-y*sin(a),x*sin(a)+y*cos(a));}
inline double pointsegmentdis(const Vector&p,const Vector&a,const Vector&b){
Vector v=b-a,v0=p-a,v1=p-b;
if(doublepos(v|v0)<0)return ~v0;
if(doublepos(v|v1)>0)return ~v1;
return fabs((v&v0)/~v);
}
};
inline void attack(){//炮塔攻击
for(int i=1;i<=num;i++){//选定目标
turret[i].havetarget=false;
turret[i].caketarget=false;
turret[i].radius=1e7;
for(auto it=ant.begin();it!=ant.end();it++){
double dis=getdis(it->x,it->y,turret[i].x,turret[i].y);
if(dis<=radius+eps){//处于攻击范围之内
turret[i].havetarget=true;//获得目标
if(it->havecake==true){
turret[i].caketarget=true;//获得拥有蛋糕的目标
turret[i].target=it;
}
else if(dis<turret[i].radius&&turret[i].caketarget==false){//一个离得最近的目标且没有获得蛋糕的目标
turret[i].radius=dis;
turret[i].target=it;
}
}
if(turret[i].caketarget==true){//有获得蛋糕的目标后break
break;
}
}
}
for(int i=1;i<=num;i++){//进行攻击
if(turret[i].havetarget==false){//没有表跳过
continue;
}
if(turret[i].caketarget==false){//没有获得蛋糕的目标
turret[i].target->hp-=damage;//近攻击离自己最近的目标
continue;
}
Vector a(turret[i].target->x,turret[i].target->y),b(turret[i].x,turret[i].y);
for(auto&x:ant){
Vector p(x.x,x.y);
if(p.pointsegmentdis(p,a,b)<=0.5+eps){//处于攻击范围之内,0.5是蚂蚁的半径
x.hp-=damage;
}
}
}
}
inline void clear(){//处理尸体
for(auto it=ant.begin();it!=ant.end();it++){
if(it->hp<0){
if(it->havecake==true){//蛋糕归位
cakefly=false;
}
mp[it->x][it->y].use=false;//清空标记
it=ant.erase(it);
it--;
livetot--;
}
}
}
inline bool gameover(){//判断游戏结束
for(auto x:ant){
if(x.havecake==true&&x.x==0&&x.y==0){
return true;
}
}
return false;
}
inline void update(){//时间流逝
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
if(mp[i][j].information){//信息素最少是0
mp[i][j].information--;
}
}
}
for(auto&x:ant){//年龄长大
x.age++;
}
}
inline void init(){
cin>>n>>m>>num>>damage>>radius;
for(int i=1;i<=num;i++){
int x,y;
cin>>x>>y;
turret[i].x=x;
turret[i].y=y;
mp[x][y].use=true;
}
cin>>endtime;
}
inline void play(){
for(tim=1;tim<=endtime;tim++){
antborn();
release();
antmove();
checkcake();
attack();
clear();
if(gameover()){
break;
}
update();
}
}
inline void print(){
if(tim==endtime+1){
cout<<"The game is going on\n";
}
else{
cout<<"Game over after "<<tim<<" seconds\n";
}
cout<<livetot<<'\n';
for(auto x:ant){
cout<<x.age<<' '<<x.level<<' '<<x.hp<<' '<<x.x<<' '<<x.y<<'\n';
}
}
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
init();
play();
print();
return 0;
}
压行版本。
#include<bits/stdc++.h>
using namespace std;
const int N=22;const double eps=1e-8;int n,m,num,radius,damage,endtime,tot,livetot,tim,dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};bool running=false,cakefly=false;
struct Map{int information=0;bool use=false;}mp[N][N];
struct Ant{int age=0,level=0,hp=0,maxhp=0;pair<int,int>pos,last;bool havecake=false;};
list<Ant>ant;
struct Turret{bool havetarget=false,caketarget=false;pair<int,int>pos;double radius;list<Ant>::iterator target;}turret[N];
struct Vector{
double x,y;
const double pi=acos(-1);
inline Vector(double a=0,double b=0){x=a,y=b;}
inline friend Vector operator+(const Vector&a,const Vector&b){return Vector(a.x+b.x,a.y+b.y);}
inline friend Vector operator-(const Vector&a,const Vector&b){return Vector(a.x-b.x,a.y-b.y);}
inline friend Vector operator*(const Vector&a,const double&b){return Vector(a.x*b,a.y*b);}
inline friend Vector operator/(const Vector&a,const double&b){return Vector(a.x/b,a.y/b);}
inline friend double operator&(const Vector&a,const Vector&b){return a.x*b.y-a.y*b.x;}//叉积
inline friend double operator|(const Vector&a,const Vector&b){return a.x*b.x+a.y*b.y;}//点积
inline double operator~()const{return sqrt(x*x+y*y);}//模长
inline double operator!()const{return atan2(y,x);}//弧度*180/pi=度数
inline double slope()const{return y/x;}
inline int doublepos(double x)const{return (fabs(x)<eps)?0:((x<0)?-1:1);}
inline Vector rotate(const double&a){return Vector(x*cos(a)-y*sin(a),x*sin(a)+y*cos(a));}
inline double pointdistosegment(const Vector&p,const Vector&a,const Vector&b){
Vector v=b-a,v0=p-a,v1=p-b;
if(doublepos(v|v0)<0)return ~v0;
if(doublepos(v|v1)>0)return ~v1;
return fabs((v&v0)/~v);
}
};
inline void antborn(){(livetot>5||mp[0][0].use==true)?0:(++tot,++livetot,ant.push_back({0,(tot-1)/6+1,(int)(4*pow(1.1,(tot-1)/6+1)),(int)(4*pow(1.1,(tot-1)/6+1)),{0,0},{0,0},false}),mp[0][0].use=true);}
inline void release(){for(auto x:ant)(x.havecake==true)?(mp[x.pos.first][x.pos.second].information+=5):(mp[x.pos.first][x.pos.second].information+=2);}
inline bool check(int x,int y){return mp[x][y].use==false&&x>=0&&y>=0&&x<=n&&y<=m;}
inline void antmove(){
for(auto&x:ant){
int pos,maxinformation=0,cnt=0;
for(int i=0,tx,ty;i<4;i++)(check(tx=x.pos.first+dx[i],ty=x.pos.second+dy[i])==true&&x.last!=pair<int,int>{tx,ty}&&mp[tx][ty].information>=maxinformation)&&(pos=i,mp[tx][ty].information>maxinformation?cnt=1,maxinformation=mp[tx][ty].information:cnt++);
if(cnt==0){x.last=x.pos;continue;}
if(cnt>1)for(int i=0,tx,ty;i<4;i++)if(check(tx=x.pos.first+dx[i],ty=x.pos.second+dy[i])&&x.last!=pair<int,int>{tx,ty}&&mp[tx][ty].information==maxinformation){pos=i;break;}
if((x.age+1)%5==0)for(int i=0,tx,ty;i<4;i++)if(((pos=(--pos<0)?3:pos)+1)&&(check(tx=x.pos.first+dx[pos],ty=x.pos.second+dy[pos])&&x.last!=pair<int,int>{tx,ty}))break;
mp[x.last.first=x.pos.first][x.last.second=x.pos.second].use=false,mp[x.pos.first+=dx[pos]][x.pos.second+=dy[pos]].use=true;
}
}
inline void checkcake(){if(cakefly==false)for(auto&x:ant)if(x.pos==pair<int,int>{n,m}){cakefly=x.havecake=true,x.hp=min(x.hp+(int)(1.0*x.maxhp/2.0),x.maxhp);break;}}
inline double distance(pair<int,int>a,pair<int,int>b){return sqrt((a.first-b.first)*(a.first-b.first)+(a.second-b.second)*(a.second-b.second));}
inline void attack(){
for(int i=1;i<=num;i++){
turret[i].havetarget=turret[i].caketarget=false,turret[i].radius=1e7;
for(auto it=ant.begin();it!=ant.end();it++){
double dis=distance(turret[i].pos,it->pos);
if(dis<=radius+eps){
turret[i].havetarget=true;
if(it->havecake==true)turret[i].caketarget=true,turret[i].target=it;
else if(dis<turret[i].radius&&turret[i].caketarget==false)turret[i].target=it,turret[i].radius=dis;
}
if(turret[i].caketarget==true)break;
}
}
for(int i=1;i<=num;i++){
if(turret[i].havetarget==false)continue;
if(turret[i].caketarget==false){turret[i].target->hp-=damage;continue;}
Vector a(turret[i].target->pos.first,turret[i].target->pos.second),b(turret[i].pos.first,turret[i].pos.second);
for(auto&x:ant){
if(x.havecake==true){x.hp-=damage;continue;}
Vector p(x.pos.first,x.pos.second);
if(p.pointdistosegment(p,a,b)<eps+0.5)x.hp-=damage;
}
}
}
inline void clear(){for(auto it=ant.begin();it!=ant.end();it++)(it->hp<0)&&(cakefly=(it->havecake==true)?false:cakefly,mp[it->pos.first][it->pos.second].use=false,it=ant.erase(it),it--,livetot--);}
inline bool gameover(){for(auto x:ant)if(x.havecake==true&&x.hp>=0&&x.pos==pair<int,int>{0,0})return true;return false;}
inline void update(){for(int i=0;i<=n;i++)for(int j=0;j<=m;j++)(mp[i][j].information)&&(mp[i][j].information--);for(auto&x:ant)x.age++;}
inline void init(){cin>>n>>m>>num>>damage>>radius;for(int i=1,x,y;i<=num;i++)cin>>x>>y,turret[i].pos={x,y},mp[x][y].use=true;cin>>endtime;}
inline void play(){for(tim=1;tim<=endtime;tim++){antborn(),release(),antmove(),checkcake(),attack(),clear();if(gameover())break;update();}}
inline void print(){(tim==endtime+1)?(cout<<"The game is going on\n",1):(cout<<"Game over after "<<tim<<" seconds\n",1);cout<<livetot<<'\n';for(auto x:ant)cout<<x.age<<' '<<x.level<<' '<<x.hp<<' '<<x.pos.first<<' '<<x.pos.second<<'\n';}
int main(){
init();
play();
print();
return 0;
}