您的位置:首页 > 其它

[YZOJ]P3238 - 电梯

2017-09-09 17:33 155 查看
YZOJ-P3238-电梯

百度百科

姿势水平还要提起来。

题意描述:

问题一:对 x,y∈N 且 ax+by<=a×b, 求 ax+by 的取值个数。

问题二:对 x,y∈N ,询问一个c ,使 c=ax+by 。最小化 x+y 。

考场情况:

写了个广搜+哈希,水过55分………

正解:线性规划

问题一:



→发现不同点对(x,y) 可能出现 ax+by 相同。

推exgcd:

x1=y2,y1=x2−[ab]y2

通解:x=xo+bgcd(a,bt,t∈Z

则在[0,bgcd(a,b)) 内点到权值映射为一对一。

→ 求这部分面积。



套个梯形面积公式就好…但是写挂了。原因是没有处理到上方线上的点,改成个割补法竟然过了。

问题二:

考虑 a,b大小。

若a=b自然很好处理。

若a>b,则使b个数尽可能少,就可以构造最优解。

由 x=xo+bgcd(a,bt,t∈Z

对 x0 进行取模等操作,构造x的最小非负整数解,并推出y即可。

#include<cstdio>
#include<algorithm>
#define R register
#define ll long long
using namespace std;

int gcd(R ll a,R ll b)
{
R ll k;
while(b!=0)
k=a,a=b,b=k%b;
return a;
}

void exgcd(ll a,ll b,ll &x,ll &y)
{
if(b==0){x=1,y=0;return;}
exgcd(b,a%b,x,y);
ll k=x;
x=y,y=k-(a/b)*y;
}

int main()
{
//freopen("2.txt","r",stdin);
R ll x0,y0,x,y;
R ll a,b,c,g,k,m;
R int Q;
scanf("%lld%lld%d",&a,&b,&Q);
if(a>b)swap(a,b);

g=gcd(a,b);
k=a*b/g-( (a/g-1)*(b/g-1)>>1 )+1;
printf("%lld\n",k);

exgcd(a,b,x0,y0);m=b/g;
while(Q--)
{
scanf("%lld",&c);
if(c%g!=0){printf("-1\n");continue;}
k=c/g%m;x=x0*k;
x=(x%m+m)%m;
y=(c-a*x)/b;
if(y<0){printf("-1\n");continue;}
printf("%lld\n",x+y);
}
return 0;
}


我的线性规划还要加强。要尽可能多参加网上的训练,尽能力的刷题了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: