description
你在一个跨国公司负责发工资,每个工人的工资以自己本国货币结算。如果你手头上有足够的该国货币,你就直接发给他;如果没有足够的该国货币,他也不介意收到其他种类的货币,前提是按兑换关系他没有少拿就可以了。例如,有六种货币:A,B,C,D,E,F,你知道这些货币的兑换关系是:
23 A = 17 B
16 C = 29 E
5 B = 14 E
1 D = 7 F
假如有个工人过来领100 A,而你手头正好没这么多A货币,你可以考虑替换成74 B(相当于100.12 A)、115 C(相当于100.72 A)或207 E(相当于100.02 A)。你应该支付207 E,因为这最接近这个工人应得的工资。
注意根据以上的兑换关系,你无法推断货币A与D、A与F的兑换关系。
由于钱仓空间有限,每种货币你最多只能持有100000,因此你无法用E货币支付64000 A,但用73078 C来支付是允许的。
假设工人领工资时,你正好没有结算的货币了,但其他货币的钱仓都是满的。你需要写一个程序帮你计算该怎样支付这个工人的工资。
analysis
-
随便搞
-
用遍历,搞出两两货币兑换的最小公倍数
-
然后换就好了
-
注意这题读入挺坑的…
code
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define ll long long
#define INF 1000000007
#define fo(i,a,b) for (ll i=a;i<=b;++i)
#define fd(i,a,b) for (ll i=a;i>=b;--i)
using namespace std;
ll f[20][20][2],g[20][20][2];
char st[15],name[15],str[15][15];
ll n,tot,val,type,ans,now;
double mn=INF;
bool bz[20];
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline bool judge(char st1[],char st2[])
{
ll len1=strlen(st1),len2=strlen(st2);
if (len1!=len2)return 0;
fo(i,0,len1-1)if (st1[i]!=st2[i])return 0;
return 1;
}
inline ll query(char st[])
{
fo(i,1,8)
{
if (strlen(str[i])==0)
{
++tot,strcpy(str[i],st);
return i;
}
if (judge(st,str[i]))return i;
}
}
inline ll gcd(ll x,ll y){return x%y==0?y:gcd(y,x%y);}
inline ll lcm(ll x,ll y){return x/gcd(x,y)*y;}
inline void dfs(ll x)
{
bz[x]=0;
fo(i,1,tot)if (f[x][i][0] && bz[i])
{
g[type][i][0]=g[type][x][0]*(lcm(g[type][x][1],f[x][i][0])/g[type][x][1]);
g[type][i][1]=f[x][i][1]*(lcm(g[type][x][1],f[x][i][0])/f[x][i][0]);
dfs(i);
}
}
int main()
{
n=read(),memset(bz,1,sizeof(bz));
fo(i,1,n)
{
ll x=0,y=0,xx=0,yy=0,len=0;
scanf("%s",&st),len=strlen(st);
fo(i,0,len-1)x=x*10+st[i]-'0';
scanf("%s",&st),len=strlen(st);
xx=query(st);
scanf("%s",&st),scanf("%s",&st),len=strlen(st);
fo(i,0,len-1)y=y*10+st[i]-'0';
scanf("%s",&st),len=strlen(st);
yy=query(st);
f[xx][yy][0]=x,f[xx][yy][1]=y;
f[yy][xx][0]=y,f[yy][xx][1]=x;
}
val=read(),scanf("%s",&name),bz[type=query(name)]=0;
fo(i,1,tot)if (type!=i && f[type][i][0])g[type][i][0]=f[type][i][0],g[type][i][1]=f[type][i][1],dfs(i);
fo(i,1,tot)if (type!=i && g[type][i][0])
{
ll tmp=ceil(1.0*g[type][i][1]/g[type][i][0]*val);
if (1.0*tmp*g[type][i][0]/g[type][i][1]-val<mn && tmp<=100000)
mn=1.0*tmp*g[type][i][0]/g[type][i][1]-val,ans=tmp,now=i;
}
printf("%lld %s\n",ans,str[now]);
return 0;
}

本文介绍了一种在跨国公司中解决工资发放问题的算法。在不同国家使用不同货币的情况下,算法通过计算货币间的兑换关系,确定如何用现有货币支付员工工资,确保支付金额最接近应得工资且不超过货币持有上限。
1124

被折叠的 条评论
为什么被折叠?



