Problem Description
Ivy_End最近得到了一大堆电容,他希望通过使用这些电容通过串联或者并联来得到一个任意电容的电路。
关于电容的串并联计算方法如下:
1. 假设两个电容为C1、C2,则串联后的电容为 C = (C1 * C2) / (C1 + C2)
2. 假设两个电容为C1、C2,则并联后的电容为 C = C1 + C2
综上所述,电容的串联计算法则与电阻的并联计算法则相同;电容的并联计算法则和电阻的并联计算法则相同。
现在Ivy_End获得了一大堆1pF的电容,他希望用他们来获得一个电容为C的电容,请问最少需要多少个1pF的电容。
关于电容的串并联计算方法如下:
1. 假设两个电容为C1、C2,则串联后的电容为 C = (C1 * C2) / (C1 + C2)
2. 假设两个电容为C1、C2,则并联后的电容为 C = C1 + C2
综上所述,电容的串联计算法则与电阻的并联计算法则相同;电容的并联计算法则和电阻的并联计算法则相同。
现在Ivy_End获得了一大堆1pF的电容,他希望用他们来获得一个电容为C的电容,请问最少需要多少个1pF的电容。
Input
多组样例(>=20,000),每组一行。
输入格式U D(U,D<=1,000,000,000,000,000,000),表示总电容C = U / D,表示希望获得的电容大小。
输入格式U D(U,D<=1,000,000,000,000,000,000),表示总电容C = U / D,表示希望获得的电容大小。
Output
每组一行。
输出格式为 Case #T: N,其中T、N分别表示样例组数、最少需要的电容数。
输出格式为 Case #T: N,其中T、N分别表示样例组数、最少需要的电容数。
Sample Input
1 1 1 2 1 3
Sample Output
Case #1: 1 Case #2: 2 Case #3: 3
Author
我的想法:
U>D,则U/D的整数部分直接用1pF并联就好了。
再考虑真分数,易得1/n的电容最少可由n个1pF的电容串联获得。每个真分数最少可以看成若干个1/i的电容并联获得(即数值相加)
例如:
3/5=1/2+1/10;
7/8=1/2+1/4+1/8;
2/5=1/5+1/5.
这里一开始需要对U%=D后的值和D/2进行比较,如果U/D大于1/2那么要选一个1/2的电容。而且接下来选的电容值的分母一定得是D的因子,这样才能保证整体数量最少。
例如:
4/5=1/2+3/10=1/2+1/5+1/10;这时总个数是2+5+10=17个。
4/5=1/2+3/10=1/2+1/4+1/20;这时总个数是2+4+20=26个,显然大了很多。
其实这是因为只有选了D的因子这样在接下来选的时候才不会使分母大于D。
可以看一下下面的代码。
#include <stdio.h>
long long gcd(long long m, long long n)
{long long t;while (m){t = n%m;n = m;m = t;}return n;
}
int main()
{//freopen("in.txt", "r", stdin);//freopen("out.txt", "w", stdout);long long u, d, ans, cases = 0,i,t;while (~scanf("%I64d%I64d", &u, &d)){t = gcd(u, d);u /= t;d /= t;ans = 0;ans += u / d;u = u%d;if (u == 0){printf("Case #%I64d: %I64d\n", ++cases, ans);continue;}else{if (u - d / 2 > 0){ans += 2;u = u * 2 - d;d = d * 2;}for (i = 3;u&&i<d;i++){if (d%i==0&&u - d / i >=0){ans += i;u -= d / i;}}if(u) ans += u*d;printf("Case #%I64d: %I64d\n", ++cases, ans);}}return 0;
}
然而,这并没有什么用!因为TLE了!
我把约分的步骤去掉又提交了一次,依然是TLE!
然后看了给的题解,没想到用到了这个结论:
使用1pF的电容得到A/BpF的电容的最少个数与得到B/ApF的最少个数相同。
说得好像很有道理,我竟无言以对,跪了!
那就一直循环迭代直到分子为0退出就好了!
#include <stdio.h>
int main()
{//freopen("in.txt", "r", stdin);//freopen("out.txt", "w", stdout);long long u, d, ans, cases = 0,t;while (~scanf("%I64d%I64d", &u, &d)){ans = 0;while (d){ans += u / d;t = u%d;u = d;d = t;}printf("Case #%I64d: %I64d\n", ++cases, ans);}return 0;
}