您的位置:首页 > 其它

HDU 1099 Lottery

2013-11-23 10:14 232 查看
题目有点难懂,直接看样例又不太直观。不管了。其实题意很简单,实际上就是一道数学题+编码

题意:求一个数x的f(x)=x*(1/1+1/2+···+1/x),并按照有分数是输出其带分数的形式。注意格式输出。

1.一开始做了溢出了,仔细看看才知道__int64貌似也不兼容22!的大小,一开始用数组记录22!的阶乘的方法不行。

2.方法很多,这里采用的是模拟手工暴力运算,先将x乘进到括号里的分数,然后相加。相加的时候将分母扩大到最小公倍数,分子相应增大,以此类推

#include <stdio.h>
#include <algorithm>
using namespace std;
#include <iostream>

__int64 gcd(__int64 x1,__int64 x2){
return x2 ? gcd(x2,x1%x2) : x1;
}
__int64 lcm(__int64 x1,__int64 x2){
return x1 / gcd(x1,x2) * x2;
}
int getl(__int64 x){
int cnt = 0;
while(x>0){
cnt++;x/=10;
}
return cnt;
}
void cal(int x)
{
int cnt = 0;
__int64 fz=x,fm=1,tx;
for(int i=2;i<=x;i++)
{
tx = lcm(fm,i);
fz *= (tx/fm);
fz += (tx/i*x);
fm = tx;
if(fz > fm) cnt+=(fz/fm) , fz %= fm;
tx = gcd(fz,fm);
fz /= tx;
fm /= tx;
}
fz %= fm;
//cout<<cnt<<' ' <<fz<<' '<<fm<<'\n';
if(fz == 0) cout<<cnt<<endl;
else
{
int l1 = getl(cnt),l2 = getl(fm);
for(int i=0;i<=l1;i++) cout<<' ';
cout<<fz<<'\n';
cout<<cnt<<' ';
for(int i=0;i<l2;i++) cout<<'-';
cout<<'\n';
for(int i=0;i<=l1;i++) cout<<' ';
cout<<fm<<'\n';
}
}

int main()
{
int n;
while(cin>>n)
{
if(n==1) cout<<"1\n";
else cal(n);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: