转换热身小塔2求解

1 篇文章 0 订阅
1 篇文章 0 订阅

https://h5mota.com/tower/?name=zhrs2

#include<cstdio>
#include<map>
#include<thread>
#include<cstring>
using namespace std;
int siz=0;int pos0;int effects=11;
int pos[16][16]={};FILE* dbg;
int atk1=1,dex1=1,mdef1=10;//宝石增加能力
int hp1=75,hp2=200,hp3=200,hp4=400;
bool graph[33][33]={};
const int maxx=1<<24;
int *addhp;
/*
map<int,int >f;
map<int,int >pre;
map<int ,bool>vis;
map<int,int>extraatk;
map<int,int>extradex;
map<int ,int>extramdef;
*/

int *f;
int *pre;
int *extraatk;
int *extradex;
int *extramdef;
bool vis[maxx];
int cnt=0;
bool vis1[20][20]={};
int hp0=728,atk0=11,dex0=11,mdef0=0;//初始能力
//int hp0=580,atk0=80,dex0=51,mdef0=105;//初始能力
int ans=0;
bool minusdamage=0;
struct enemy{
	int hp,atk,dex,spj;
	double spj2[14];
}enemys[44]={};
int tou,wei,*q1,*q2,*q3;
int st0=0;
struct ff{
int x,y;}q[3333]={};
void calc1()
{
	for(int i=1;i<=siz;i++)
		pos[i][0]=pos[i][i]=1;
		
}
//int enemy0[99]={5,9,7,8,6,7,7,1,9,10,8,2,7,3,4,8};
int enemy0[99]={1,2,3,7,0,4,1,8,2,1,0,5,0,8,0,7,4,7,2,3,0,8,6,2};
int weak[99]={};
int fight2(int myhp,int myatk,int mydex,int mymdef,enemy id,int weak=0)
{
	//printf("%d\n",++cnt);
	int klk=0;
	if(myhp<=0)return 0;
	double damagerate=1;
	double extradamage=0;//固伤,魔防有效
	double extradamage2=0;//固伤,无视魔防
	if(myatk<=id.dex)return 0;
	if(id.spj==2147483647)
		return myhp+id.spj2[0];
	for(int i=0;i<effects;i++)
		if(id.spj&(1<<i))	
			switch(i)
			{
				
				case 1://魔攻
				mydex=0;break;
				
				case 7://净化
				extradamage+=mymdef*id.spj2[klk++];
				break;
				
				case 2://固伤
				extradamage2+=id.spj2[klk++];
				break;
				
				case 3://吸血,不加到自己生命
				myhp=myhp-(int)(myhp*(id.spj2[klk++]));
				break;
				
				case 4://吸血,加到自己生命
				id.hp+=myhp*id.spj2[klk++];
				//myhp=myhp*(1-id.spj2[klk++]);
				myhp=myhp-(int)(myhp*(id.spj2[klk++]));
				break;
				
				case 5://X连击
				damagerate=id.spj2[klk++];
				break;
				
				case 6://坚固
				myatk=id.dex+1;
				break;
				
				case 0://模仿
				id.atk=max(id.atk,myatk);
				id.dex=max(id.dex,mydex);
				break;
				
				case 8://先攻
				id.hp+=myatk-id.dex;
				break;
				
				case 9://破甲
				extradamage+=id.spj2[klk++]*mydex;
				break;
				
				case 10://反击
				extradamage+=((id.hp-1)/(myatk-id.dex)+1)*(int)(myatk*id.spj2[klk++]);
				break;
			}
	if(myatk-id.dex<=0)return 0;
	int alldamage=(id.hp-1)/(myatk-id.dex)*(id.atk-mydex)*damagerate-mymdef;
	alldamage+=extradamage;
	if(alldamage<0&&!minusdamage)
		alldamage=0;
	alldamage+=extradamage2;
	if(myhp-alldamage<=0)return 0;
	else return myhp-alldamage;
}
int fight(int myhp,int myatk,int mydex,int mymdef,enemy id,int tmm=0)
{
	switch(tmm)
	{
	case 8:
		myhp=fight2(myhp,myatk,mydex,mymdef,enemys[3]);
		myhp=fight2(myhp,myatk,mydex,mymdef,enemys[0]);
		myhp=fight2(myhp,myatk,mydex,mymdef,enemys[0]);
		return myhp;
		case 9:
		myhp=fight2(myhp,myatk,mydex,mymdef,enemys[0]);
		myhp=fight2(myhp,myatk,mydex,mymdef,enemys[1]);
		myhp=fight2(myhp,myatk,mydex,mymdef,enemys[1]);
		return myhp;
		case 6:
		myhp=fight2(myhp,myatk,mydex,mymdef,enemys[4]);
		myhp=fight2(myhp,myatk,mydex,mymdef,enemys[1]);
		myhp=fight2(myhp,myatk,mydex,mymdef,enemys[1]);
		myhp=fight2(myhp,myatk,mydex,mymdef,enemys[0]);
		return myhp;
		case 7:
		myhp=fight2(myhp,myatk,mydex,mymdef,enemys[1]);
		myhp=fight2(myhp,myatk,mydex,mymdef,enemys[3]);
		myhp=fight2(myhp,myatk,mydex,mymdef,enemys[3]);
		myhp=fight2(myhp,myatk,mydex,mymdef,enemys[5]);
		return myhp;
		default:
		return fight2(myhp,myatk,mydex,mymdef,id);
		
	}
}
char map0[13][13]={//5,6,7宝石,1-4血瓶 
	{19,19,5,0,6,19,20,19,19,1,0,5,20},
	{19,19,19,19,0,0,0,20,0,19,1,19,6},
	{19,19,19,1,0,19,19,20,0,20,0,19,0},
	{5,0,19,0,20,19,5,1,19,20,19,19,19},
	{20,19,19,19,0,19,19,19,19,0,19,19,0},
	{0,0,20,19,20,19,19,19,0,0,0,20,2},
	{20,19,19,19,0,19,19,19,19,19,6,0,19},
	{0,1,0,0,0,19,20,0,20,0,20,19,5},
	{20,19,19,19,20,0,0,19,20,19,6,20,0},
	{6,20,0,0,0,19,0,19,19,19,0,19,19},
	{0,19,20,19,19,0,0,19,0,2,20,20,0},
	{20,19,0,19,0,0,0,19,19,19,19,19,5},
	{0,0,0,0,0,0,0,0,19,0,0,0,5},
	
};
char map1[13][13]={};
bool check(int s,int i)
{
	if(st0&(1<<i))
		return true;
	for(int j=0;j<siz;j++)
		if(i!=j&&graph[i][j])
			return true;
	return false;
}

void bfs(int x,int y,char map11[13][13])
{
	int tou=0,wei=0;
	memset(vis1,0,sizeof(vis1));
	vis1[x][y]=1;
	q[0].x=x,q[0].y=y;
	while(tou<=wei)
	{
		int tx=q[tou].x,ty=q[tou].y;
		if(tx>0&&!vis1[tx-1][ty])
		{
			vis1[tx-1][ty]=1;
			if(map11[tx-1][ty]<19)
				q[++wei].x=tx-1,q[wei].y=ty;
		}
		if(tx<12&&!vis1[tx+1][ty])
		{
			vis1[tx+1][ty]=1;
			if(map11[tx+1][ty]<19)
				q[++wei].x=tx+1,q[wei].y=ty;
		}
		if(ty>0&&!vis1[tx][ty-1])
		{
			vis1[tx][ty-1]=1;
			if(map11[tx][ty-1]<19)
				q[++wei].x=tx,q[wei].y=ty-1;
		}
		if(ty<12&&!vis1[tx][ty+1])
		{
			vis1[tx][ty+1]=1;
			if(map11[tx][ty+1]<19)
				q[++wei].x=tx,q[wei].y=ty+1;
		}
		tou++;
	}
}
void makegraph()
{
	int idd=19;
	for(int i=12;i>=0;i--)
		for(int j=0;j<=12;j++)
			if(map0[i][j]==20)
				map0[i][j]=++idd,siz++;
	for(int i=0;i<=12;i++)
		for(int j=0;j<=12;j++)
			if(map0[i][j]>19){
				bfs(i,j,map0);
				int tm=map0[i][j]-20;
				for(int i=0;i<=12;i++)
					for(int j=0;j<=12;j++)
						if(vis1[i][j]&&map0[i][j]>19)
							graph[tm][map0[i][j]-20]=graph[map0[i][j]-20][tm]=1;	
			}
	bfs(12,6,map0);
	for(int i=0;i<=12;i++)
		for(int j=0;j<=12;j++)
			if(map0[i][j]>19&&vis1[i][j])
				st0|=(1<<map0[i][j]-20);
}
bool check0(int st,int add)
{
	if(st0&(1<<add))return 1;
	for(int i=0;i<siz;i++)
		if((st&(1<<i))&&graph[i][add])
			return true;
	return false;
}
int getserv(int st)
{
	if(st==0x3ffffff)
		int dfgasdg=0;
	memcpy(map1,map0,sizeof(map0));
	for(int i=0;i<13;i++)
		for(int j=0;j<13;j++)
			if(map1[i][j]>19)
			{
				int tm=map1[i][j]-20;
				if(st&(1<<tm))
					map1[i][j]=0;
			}
	bfs(12,6,map1);
	int tmphp=0;
	int atk=0,dex=0,mdef=0;
	for(int i=0;i<13;i++)
		for(int j=0;j<13;j++)
			if(vis1[i][j])
				switch(map0[i][j])
				{
					case 5:
					atk+=atk1;
					break;
					case 6:
					dex+=dex1;
					break;
					case 7:
					mdef+=mdef1;
					break;
					case 1:
					tmphp+=hp1;
					break;
					case 2:
					tmphp+=hp2;
					break;
					case 3:
					tmphp+=hp3;
					break;
					case 4:
					tmphp+=hp4;
					break;
					
				}
	extraatk[st]=atk;
	extradex[st]=dex;
	return tmphp;
}
bool uuuu(int s,int t)
{
	for(int i=0;i<siz;i++)
		if((s&(1<<i))==0&&(t&(1<<i))>0)
			return 1;
	return 0;
}
bool isfinish(int i)//自定义函数,表示状态i可以作为最终状态,那么可以比较最终结果
{
	return((i>>22)&1)==1;
}
void dp(int x)
{
	q3=q1,q1=q2,q2=q3;//q1新,q2旧 
	int allsiz=wei;
	tou=0,wei=-1;
	for(int i=0;i<=allsiz;i++)//提取上一层dp结果
	{
		int te=q2[i];
		if(f[te]==0&&f[te|maxx]==0)
			continue;
		for(int j=0;j<siz;j++)
		{
			int tm=te|(1<<j);
			if(tm!=te&&!vis[tm])
			{
				vis[tm]=1;
				if(check0(te,j))
					q1[++wei]=tm;
			}
		}
	}
	//多线程
	for(int i=0;i<=wei;i++)
	{
		int te=q1[i];//队列不计入衰弱
		addhp[te]=getserv(te);
		if(te==0x216006)
			int agadsgsd=0; 
		for(int j=0;j<siz;j++)
			if(te&(1<<j))
			{
				int tm=te^(1<<j);
				int tmm=enemy0[j];
				if(tmm>=8)
				{
					if(f[tm]>0&&f[tm]+addhp[te]-addhp[tm]>f[te])
						f[te]=f[tm]+addhp[te]-addhp[tm],pre[te]=tm,extramdef[te]=extramdef[tm]+mdef1;
					continue;
				}
				int tmp=fight2(f[tm],extraatk[tm]+atk0,extradex[tm]+dex0,extramdef[tm]+mdef0,enemys[enemy0[j]],tmm);
				if(tmp>0)
					tmp=tmp+addhp[te]-addhp[tm];//不衰弱里打
				if(tmp>f[te])//转移
						f[te]=tmp,pre[te]=tm,extramdef[te]=extramdef[tm];

			}
		if(f[te]>0)//如果这个状态能走到
		{	
			
			
			fprintf(dbg,"%x %d %d %d %d %x\n",te,f[te],atk0+extraatk[te],dex0+extradex[te],mdef0+extramdef[te],pre[te]);
		
			if(isfinish(te))//可以是最终状态
			{
				if(ans<f[te])//lock
					ans=f[te],pos0=te;
			}
		}
	}
	
	
	//多线程
}
void getpos(int s)
{
	while(s)
	{
		int ss=pre[s];
		int sss=(s^ss)&maxx-1;
		for(int i=0;i<=12;i++)
			for(int j=0;j<=12;j++)
				if(sss==(1<<map0[i][j]-20)&&map0[i][j]>19)
					printf("%x %x (%d,%d),hp=%d,atk=%d,dex=%d,mdef=%d\n",s,pre[s],i,j,f[ss],extraatk[ss&maxx-1]+atk0,extradex[ss&maxx-1]+dex0,extramdef[ss&maxx-1]+mdef0);
		s=pre[s];
	}
}
int main()
{
	
	f=new int[1LL*maxx*2-1];
	pre=new int[1LL*maxx*2-1];
	extraatk=new int[maxx];
	extradex=new int[maxx];
	extramdef=new int[maxx];
	addhp=new int[maxx];
	memset(f,0,sizeof(int)*(1LL*maxx*2-1));
	memset(pre,0,sizeof(int)*(1LL*maxx*2-1));
	memset(extraatk,0,sizeof(int)*maxx);
	memset(extradex,0,sizeof(int)*maxx);
	memset(extramdef,0,sizeof(int)*maxx);
	memset(addhp,0,sizeof(int)*maxx);
	q1=new int[2999999];
	q2=new int[2999999];
	enemys[0]={55,18,3,0,{}};
	enemys[1]={35,22,5,0,{}};
	enemys[2]={92,14,8,(1<<8)+(1<<10),{0.1}};
	enemys[3]={50,29,1,(1<<5)+(1<<7),{2,3}};
	enemys[4]={68,34,4,0,{}};
	enemys[5]={50,70,0,0,{}};
	enemys[6]={95,96,8,0,{}};
	enemys[7]={23,18,11,1<<6,{}};
	makegraph();
	q1[0]=0,tou=0,wei=0;
	dbg=fopen("debug.log","wb");
	for(int i=0;i<siz;i++)
	{
		for(int j=0;j<siz;j++)
			fprintf(dbg,"%d ",graph[i][j]);
		fprintf(dbg,"\n");
	}
	for(int i=0;i<siz;i++)
		if(st0&(1<<i))
			fprintf(dbg,"%d ",i);
	fprintf(dbg,"\n");
	f[0]=hp0;
	
	for(int i=1;i<=siz;i++)
		dp(i);
	//dp();
	printf("%x %d\n",pos0,ans);
	getpos(pos0);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值