求助,请观察一个普通问题的dalao解法
  • 板块学术版
  • 楼主content
  • 当前回复2
  • 已保存回复2
  • 发布时间2021/8/3 10:15
  • 上次更新2023/11/4 12:10:16
查看原帖
求助,请观察一个普通问题的dalao解法
429854
content楼主2021/8/3 10:15
#include<iostream>
#include<cstdio>
#include<map>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>

using namespace std;

typedef long long ll;
#define re register

inline ll read()
{
    char c=getchar();ll f=1,d=0;
    while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0' && c<='9'){d=(d<<3)+(d<<1)+(c^48);c=getchar();}
    return d*f;
}

ll n;
struct Val
{
	ll rd,dv,qf;
	// remainder剩余, division分开, qualified保留(大概) 
}a[3];

inline bool ValCmp(Val x,Val y) 
{
	if(x.qf!=y.qf)return x.qf<y.qf;
	if(x.dv-x.rd!=y.dv-y.rd)return x.dv-x.rd<y.dv-y.rd;
	return x.rd<y.rd;
}

int main()
{
	n=read();
	for(re ll i=0;i<3;++i)a[i].rd=read();
	for(re ll i=0;i<3;++i)a[i].dv=read(); 
	for(re ll i=0;i<3;++i){
		a[i].qf=a[i].rd/a[i].dv;
		a[i].rd=a[i].rd%a[i].dv;
	}
	sort(a,a+3,ValCmp);
    if(a[0].qf==a[1].qf && a[1].qf==a[2].qf)
	{
        allplus://??
        if(n>=a[0].dv+a[1].dv+a[2].dv-a[0].rd-a[1].rd-a[2].rd)
		{
            n-=(a[0].dv+a[1].dv+a[2].dv-a[0].rd-a[1].rd-a[2].rd);
            ++a[0].qf;++a[1].qf;++a[2].qf;
            a[0].rd=0;a[1].rd=0;a[2].rd=0;
        }
		else
		{
            printf("%lld\n",a[0].qf);
            return 0;
        }
        ll plus=n/(a[0].dv+a[1].dv+a[2].dv);
        printf("%lld\n",a[0].qf+plus);
        return 0;
    }

    if(a[0].qf==a[1].qf)
	{
        twoplus:
        if(n>=a[0].dv+a[1].dv-a[0].rd-a[1].rd)
		{
            n-=(a[0].dv+a[1].dv-a[0].rd-a[1].rd);
            ++a[0].qf;++a[1].qf;
            a[0].rd=0;a[1].rd=0;
        }
		else
		{
            printf("%lld\n",a[0].qf);
            return 0;
        }
        if(a[0].qf!=a[2].qf)
		{
            ll delta=a[2].qf-a[0].qf;
            if(n>=delta*(a[0].dv+a[1].dv))
			{
                n-=delta*(a[0].dv+a[1].dv);
                a[0].qf=a[2].qf;a[1].qf=a[2].qf;
            }
			else
			{
                ll plus=n/(a[0].dv+a[1].dv);
                printf("%lld\n",a[0].qf+plus);
                return 0;
            }
        }
        goto allplus;
    }

    if(n>=a[0].dv-a[0].rd)
	{
        n-=(a[0].dv-a[0].rd);
        ++a[0].qf;a[0].rd=0;
    }
    if(a[0].qf!=a[1].qf)
	{
        ll delta=a[1].qf-a[0].qf;
        if(n>=delta*a[0].dv)
		{
            n-=delta*a[0].dv;
            a[0].qf=a[1].qf;
        }
		else
		{
            ll plus=n/a[0].dv;
            printf("%lld\n",a[0].qf+plus);
            return 0;
        }
    }
    goto twoplus;//?? 
	return 0;
}
/*先预处理初始时三项能力分别能点多少元点。从小的开始补充,特判即可。*/ 

这是题目:Omori 打怪得到了n 点技能点。他可以把这些技能点点到攻击、防御、血量上。 初始时,Omori 有a 点攻击,b点防御和c 点血量。每点一点技能点,他的攻击力 / 防御力 / 血量就会上升一点。 同时,Omori 可以牺牲a1点攻击力、b1点防御力和c1点血量,以获得一点元点。牺牲操作是可以使用多次的,当攻击力小于a1或防御力小于b1 或血量小于c1时,无法执行牺牲操作。 需要指出的是,一次牺牲操作之后,攻击力、防御力和血量可以等于0。 Omori 想知道,在合理利用这些技能点的情况下,最多能获得多少点元点。

这是输入格式:第一行,一个正整数n,表示技能点的个数。 第二行,三个正整数 a,b,c表示初始的攻击力、防御力和血量。 第三行,三个正整数a1,b1,c1 ,表示每次牺牲需要耗费的攻击力、防御力和血量。

这是样例: 789123935 3578287 1128793 7003034 8590203 5782982 6001022 输出:39

因为我是直接暴力加优化做的,样例过完but超时了,然后dalao的代码还不是我能看懂的程度,有些写法没见过emmmm,希望有大佬能简单分析一下,或者还有其他写法吗?orz

2021/8/3 10:15
加载中...