c++程序的意外输出
Unexpected output of c++ program
我正在解决 http://codeforces.com/problemset/problem/552/B。
在我的第一次尝试中,我想到了类似的东西:
#include <bits/stdc++.h>
using namespace std;
int digit(long a){
int i=0;
while(a){
a/=10;
i++;
}
return i;
}
int main()
{
long n;
long long s=0;
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin>>n;
int dig=digit(n),i=0;
while(i<dig){
s+=(n-pow(10,i)+1);
i++;
}
cout<<s;
return 0;
}
但对于输入
1000000
我的程序输出了
5888895
我期待
5888896
在第二次尝试中,我为自己编写了 pow 函数:
#include <bits/stdc++.h>
using namespace std;
int digit(long a){
int i=0;
while(a){
a/=10;
i++;
}
return i;
}
long long pow1(int a){
long long s=1;
while(a--){
s*=10;
}
return s;
}
int main()
{
long n;
long long s=0;
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin>>n;
int dig=digit(n),i=0;
while(i<dig){
long long aux=pow1(i);
s+=(n-aux+1);
i++;
}
cout<<s;
return 0;
}
这次是 correct.How 可以解释一下它背后的工作原理吗?
这里可能不需要pow
。这按预期工作并且速度更快。
#include <iostream>
typedef unsigned long long ull;
using namespace std;
ull count(ull n) {
ull i = 0;
for (; n; ++i) n /= 10;
return i;
}
int main() {
ull n;
cin >> n;
ull digits = count(n);
ull ans = digits * (n + 1);
for (ull i = 0, j = 1; i < digits; ++i, j *= 10)
ans -= j;
cout << ans;
return 0;
}
所有测试用例都通过了codeforces.com
你只需要将 pow(10,i-1) 乘以 0.1。这将完成您需要的工作。
#include <iostream>
#include <cmath>
using namespace std;
int digit_calc(long long num);
long long digit_counter(long long num, int digit);
int main()
{
long long num,digit,total;
cin>>num;
digit=digit_calc(num);
total=digit_counter(num, digit);
cout<<total<<endl;
return 0;
}
int digit_calc(long long num){
int digit=0;
while(num){
digit++;
num=num/10;
}
return digit;
}
long long digit_counter(long long num, int digit){
long long sup,net,total=0;
while(num){
sup=0.1*(pow(10,digit)-1);
net=num-sup;
total=total+(net*digit);
num=sup;
digit--;
}
return total;
}
它通过了 codeforce 上的所有测试用例。
内置 pow
函数的问题在于它不像您的函数那样准确。 pow
计算 x 到 y 为 exp(y*log(x))
。这个通用公式适用于所有(甚至非整数)指数,其性能(大部分)独立于参数。该公式的问题在于,pow(10,2)
可能是 99.9
,在转换为整数类型时会被截断为 99。尝试 pow(10,i) + 0.5
执行正确的舍入。
我正在解决 http://codeforces.com/problemset/problem/552/B。
在我的第一次尝试中,我想到了类似的东西:
#include <bits/stdc++.h>
using namespace std;
int digit(long a){
int i=0;
while(a){
a/=10;
i++;
}
return i;
}
int main()
{
long n;
long long s=0;
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin>>n;
int dig=digit(n),i=0;
while(i<dig){
s+=(n-pow(10,i)+1);
i++;
}
cout<<s;
return 0;
}
但对于输入
1000000
我的程序输出了
5888895
我期待
5888896
在第二次尝试中,我为自己编写了 pow 函数:
#include <bits/stdc++.h>
using namespace std;
int digit(long a){
int i=0;
while(a){
a/=10;
i++;
}
return i;
}
long long pow1(int a){
long long s=1;
while(a--){
s*=10;
}
return s;
}
int main()
{
long n;
long long s=0;
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin>>n;
int dig=digit(n),i=0;
while(i<dig){
long long aux=pow1(i);
s+=(n-aux+1);
i++;
}
cout<<s;
return 0;
}
这次是 correct.How 可以解释一下它背后的工作原理吗?
这里可能不需要pow
。这按预期工作并且速度更快。
#include <iostream>
typedef unsigned long long ull;
using namespace std;
ull count(ull n) {
ull i = 0;
for (; n; ++i) n /= 10;
return i;
}
int main() {
ull n;
cin >> n;
ull digits = count(n);
ull ans = digits * (n + 1);
for (ull i = 0, j = 1; i < digits; ++i, j *= 10)
ans -= j;
cout << ans;
return 0;
}
所有测试用例都通过了codeforces.com
你只需要将 pow(10,i-1) 乘以 0.1。这将完成您需要的工作。
#include <iostream>
#include <cmath>
using namespace std;
int digit_calc(long long num);
long long digit_counter(long long num, int digit);
int main()
{
long long num,digit,total;
cin>>num;
digit=digit_calc(num);
total=digit_counter(num, digit);
cout<<total<<endl;
return 0;
}
int digit_calc(long long num){
int digit=0;
while(num){
digit++;
num=num/10;
}
return digit;
}
long long digit_counter(long long num, int digit){
long long sup,net,total=0;
while(num){
sup=0.1*(pow(10,digit)-1);
net=num-sup;
total=total+(net*digit);
num=sup;
digit--;
}
return total;
}
它通过了 codeforce 上的所有测试用例。
内置 pow
函数的问题在于它不像您的函数那样准确。 pow
计算 x 到 y 为 exp(y*log(x))
。这个通用公式适用于所有(甚至非整数)指数,其性能(大部分)独立于参数。该公式的问题在于,pow(10,2)
可能是 99.9
,在转换为整数类型时会被截断为 99。尝试 pow(10,i) + 0.5
执行正确的舍入。