您的位置:首页 > 其它

GYM 100883 H.tourists(一元线性同余方程)

2017-03-16 14:49 387 查看
Description

n名游客坐船,第一种船一次可以带n1个人,花费c1,第二种船一次可以带n2个人,花费c2,求这n名游客坐船所花的最小花费对应的两种船的数量

Input

多组用例,每组用例首先输入游客数量n,之后输入第一种船的花费c1和容量n1,然后输入第二种船的花费c2和容量n2

Output

如果x艘第一种船和y艘第二种船恰可以带走n名游客输出所有满足条件中最小花费对应的x和y,如果不存在合法方案则输出failed

Sample Input

43

1 3

2 4

40

5 9

5 12

0

Sample Output

13 1

failed

Solution

x*n1+y*n2=n,解次一元线性同余方程可以得到所有合法的(x,y)对,找到使得x*c1+y*c2最大的(x,y)即为答案

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 1111
ll extend_gcd(ll a,ll b,ll &x,ll &y)
{
ll d=a;
if(b)d=extend_gcd(b,a%b,y,x),y-=(a/b)*x;
else x=1,y=0;
return d;
}
ll T,n,n1,n2,c1,c2;
bool linear(ll a,ll b,ll c)//求解一元线性同余方程ax=b(mod c)
{
ll x,y;
ll g=extend_gcd(a,c,x,y);
if(b%g)return 0;
x=x*(b/g);
int mod=c/g;
x=(x%mod+mod)%mod;
y=(b-a*x)/c;
if(y<0)return 0;
ll ans=c1*x+c2*y,ansx=x,ansy=y;
for(int i=1;i<mod;i++)
{
x+=mod,y-=a/g;
if(y<0)break;
if(c1*x+c2*y<ans)
ans=c1*x+c2*y,ansx=x,ansy=y;
}
printf("%I64d %I64d\n",ansx,ansy);
return 1;
}
int main()
{
while(~scanf("%I64d",&n),n)
{
scanf("%I64d%I64d%I64d%I64d",&c1,&n1,&c2,&n2);
if(!linear(n1,n,n2))printf("failed\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: