好吧,我又来不务正业了,UESTC-28题链接:
http://acm.uestc.edu.cn/#/problem/show/28
这道题没涉及什么算法,自己写了个暴力破解的版本如下,但是运行时间太长了,百思不得其优化算法,于是到网上搜索合适的代码。。
#include<cstdio>
#include<cstdlib>
typedef struct node
{
int A;
int T;
}node;
void func(node* cai,int n,int myA,int bossH);
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
if(n<=1)break;//输入竞争补刀的玩家个数
node * cai=(node *)malloc(sizeof(node)*(n-1));//创建竞争补刀的敌方单位 cai,都是些菜,想跟我补刀?
int ii=0;
int myA,bossH;
while(ii<n-1)
{
scanf("%d%d",&cai[ii].A,&cai[ii].T);
ii++;
}
scanf("%d%d",&myA,&bossH);
func(cai,n,myA,bossH);
free(cai);
}
return 0;
}
void func(node* cai,int n,int myA,int bossH)
{
int sumA=0;
int t=1;//按时间来算伤害
int T_start,T_end;
int H_kill=bossH-myA;//斩杀线
int flag=1;//标记T_start计数器
while(t )
{
int pri_sumA=sumA;//当前t时间之前一个时刻(t-1)的boss损失血量
for(int i=0;i<n-1;i++)//求出最早出手时间T_start,和boss的致死时间T_dead ,以及最晚出手时间
{
if(t%cai[i].T==0)sumA+=cai[i].A;//sumA是BOSS已损血量
}
if(sumA>=H_kill && flag)//达到斩杀线,且之后不再计算
{
T_start=t;
flag=0;
}
if(sumA>=bossH)
{
T_end=t;
break;
}
++t;
}
while(T_start<=T_end)
{
int flagg=1;
for(int i=0;i<n-1;i++)
{
if(T_end%cai[i].T==0)
{
if(cai[i].A>myA)
{
T_end--;
flagg=0;
break;
}
}
}
if(flagg)break;
}
while(T_start<=T_end)
{
int flagg=1;
for(int i=0;i<n-1;i++)
{
if(T_start%cai[i].T==0)
{
if(cai[i].A>myA)
{
T_start++;
flagg=0;
break;
}
}
}
if(flagg)break;
}
if(T_start>T_end)
{
printf("Impossible\n");
return;
}
else
{
printf("%d %d\n",T_start,T_end);
return ;
}
}
#include<stdio.h>
int k;
struct stu
{
int x;// 时间间隔为T的时候DPS之和,输出的最大伤害
int mx;//时间间隔为T的时候最大的DPS
}bu[110];//bu[T],按时间点T创建的结构体数组
int f(int j)
{
int i,m=0,mxx=0;
for(i=1;i<=100;i++)
if(bu[i].mx)
m=m+(j/i)*bu[i].x;
return m;
}
int main()
{
int i,j,x,t,m,n,P,H,l,mxx;//
double s,x1,t1,n1,y1;//s代表所有彩笔的单位时间DPS之和 ,n1是斩杀线/单位时间只和
while(scanf("%d",&n)&&n)
{
for(i=0;i<=100;i++)
bu[i].mx=bu[i].x=0;//bu[]赋初值
s=0;
for(i=1;i<n;i++)//这里的i只计数,不干别的
{
scanf("%d%d",&x,&t);
bu[t].x=bu[t].x+x;//bu[t]代表时间t时刻,所有彩笔的当前输出总和
if(x>bu[t].mx)bu[t].mx=x;//时间t时刻,当前的最大输出记录为bu[t].mx
x1=x;
t1=t;
s=s+x1/t1;//s是所有彩笔的单位时间DPS之和,用来计算靠近斩杀线的时间
}
scanf("%d%d",&P,&H);
x1=H;
y1=P;
n1=(x1-y1)/s;//n1是靠近斩杀线的时间 下一步赋值为n
n=n1;
if(n==0)n=1;
l=0;
for (i=n;i<=100+n;i++)//从靠近斩杀线的时间n开始枚举
{ m=0;mxx=0;
for(j=1;j<=100;j++)//时间t的枚举,从1到100;
{
if(bu[j].mx)
{
m=m+(i/j)*bu[j].x;//m是输出伤害j时间下,输出次数*输出伤害=总输出数
if(i%j==0&&bu[j].mx>mxx)
mxx=bu[j].mx;//所有时刻的最高输出???不明白 buj.x改为mx
}
}
if(m+P>=H&&mxx<=P){l=i;break;}//P是我的输出,m是总伤害
else if(m+P>=H)
break;
}
if(l==0)
{
printf("Impossible\n");
continue;
}
printf("%d",l);
n1=x1/s;
n=n1;
for(j=n+100;j>=l;j--)
{
m=0; mxx=0;
for(i=1;i<=100;i++)
{
if(bu[i].mx)
{
m=m+(j/i)*bu[i].x;
if(j%i==0&&bu[i].mx>mxx)
mxx=bu[i].mx;
}
}
if(m+P>=H&&mxx<=P&&f(j-1)<H){printf(" %d\n",j);break;}
}
}
return 0;
}
心得:结构体数组的构建,暴力方法无法破解,要考虑换个方式创建个合适的数组,嗯,思维要灵活!!!感谢果爷给我的讲解~