2888
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
double n, m, k, saving;
while(cin >> n >> k >> m)
{
int flag = 1;
double price = 270;
saving = n;
while(flag <= 30 && saving < price)
{
saving += (n *= (1 + m / 100)), price *= (1 + k / 100), flag++;
//cout << saving << ',' << price << ',' << flag << endl;
}
if(saving >= price) cout << flag << endl;
else cout << "Impossible" << endl;
}
return 0;
}
注意薪资是在n的基础上每一年都在前一年的基础上*(1 + m/100)
另外就是:一定要在while循环内定义price!!不然它会保留上一次最后的房价
2895 计算循环节
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
int *remainder, *quotient, m, n;
while(cin >> m)
{
cin.get();
cin >> n;
cin.get();
remainder = new int[n];
quotient = new int [n];
for(int i = 0; i < n; i++) remainder[i] = quotient[i] = -1;
for(int i = 0; i < n; i++)
{
remainder[m] = i;
quotient[i] = (m *= 10) / n;
m %= n;
if(m == 0)
{
cout << 0 << endl;
break;
}
if(remainder[m] != -1)
{
for(int j = remainder[m]; j <= i; j++)
cout << quotient[j];
cout << endl; break;
}
}
delete remainder;
delete quotient;
}
return 0;
}
计算余数的过程上面写的很清楚了:
每一次计算余数,储存在一个数组内;余数*10,再进行下一次除法
除的商储作为另一个数组的下标,其中储存每一次进行除法的次数-1,直到出现了重复的商,这时候就可以从原本这个商的位置储存的标号开始一直循环到当前的i(因为当前的i已经计算并储存了,而下一位的i才是重复的那个下标)输出该位置的余数
3024 涉及浮点数的精度问题
double类型计算貌似会丢失精度,查了一下大概是15位可以保证,16位不一定(十进制)。(请自行查查计算机系统关于阶码的部分)
#include <iostream>
#include <string>
using namespace std;
int main(int argc, const char * argv[])
{
int n;
cin >> n;
for(int i = 0; i < n; i++)
{
string eight;
int *result = new int[3 * n + 1];
cin >> eight;
int idx = eight.length() - 1, bit = 0;
for(int i = idx; i > 1; i--)
{
int j = 0, num = eight[i] - '0';
for(; (j < bit) || num; j++)
{
int temp = num * 10 + (j < bit ? result[j] : 0);
result[j] = temp / 8;
num = temp % 8;
}
bit = j;
}
result[bit] = '\0';
cout << "case #" << i << ":" << endl;
cout << "0.";
for(int j = 0; j < bit; j++) cout << result[j];
cout << endl;
delete[] result;
}
return 0;
}
oj平台貌似不能用new(会出错?)
理一下基本思路: 从八进制小数的最后一位开始计算,*10然后/8,商存入第一位,num储存余数,若余数不为0,继续循环直至余数为0。
然后向前一位,再次循环,只不过这次多了条件 j < idx时要加上j位置上已经计算的出来的值(idx 为每一次计算后的小数位数,j会每一次从0开始算起),然后接着除以8取商取余数
小数转分数
(1)循环小数分为:纯循环小数和混循环小数.
(2)源纯循环小数的化法是:
如,0.【ab】(ab循环)=(ab/99),最后化简zhidao.
(3)混循环小数的化法是:
如,0.a【bc】(bc循环)=(abc-a)/990.最后化简.
#include <iostream>
#include <string>
using namespace std;
long long gcd(long long a, long long b)
{
if(a > b)
{
while(a % b)
{
long long temp = a % b;
a = b;
b = temp;
}
return b;
}
else return gcd(b, a);
}
int main(int argc, const char * argv[])
{
int n;
cin >> n;
for(int i = 0; i < n; i++)
{
long long a, b = 0, c, mark = 0;
string n;
cin >> a;
cin.get();
cin >> n;
cout << "case #" << i << ":" << endl;
if(n[n.size() - 1] != ']')
{
c = 1;
for(int i = 0; i < n.size(); i++)
{
b = (b * 10 + n[i] - '0');
c *= 10;
}
}
else
{
c = 0;
int flag = 0;
while(n[flag] != '[') flag++;
for(int i = 0; i < flag; i++) b = (b * 10 + n[i] - '0');
n = n.substr(flag + 1);
mark = b;
for(int i = 0; i < n.size() - 1; i++)
{
b = (b * 10 + n[i] - '0');
c = (c * 10 + 9);
}
while(flag--) c *= 10;
}
b += a * c - mark;
long long GCD = gcd(b, c);
cout << b / GCD << '/' << c / GCD << endl;
}
return 0;
}
浮点数模运算
原来解决精度问题的根本在于除了float double还有一个数据类型叫long double(?)简直惊的我下巴都掉了。