目录
1049 Counting Ones
解析
小学奥数题
枚举每一位上为1的数的个数,对每一位进行分情况讨论。
假设N可以表示成abcdefg,其中每一位代表一个0-9的数字,假如当前枚举到了从大到小的第4为,即d所在的数位,我们对d进行分情况讨论:
1. d < 1:则前3位可以选择0 ~ abc - 1 后3位可以选择 0 ~ 999
2. d = 1:
前3位可以选择0 ~ abc - 1 后3位可以选择0~999
前3位可以选择abc 后3位可以选择0 ~ efg
3. d > 1:前3位可以选择0 ~ abc 后3位可以选择0-999
可以看到,枚举每一位时用到的数有abc, efg 以及10的k次方(k为从小到大的位数),在每次循环内部先将该三个变量预处理,在累加结果时方便直接调用
注意点
#include <iostream>
#include <vector>
using namespace std;
int calc(int n){
vector<int> nums;
while (n) nums.push_back(n % 10), n /= 10;
int res = 0; //存答案
for (int i = nums.size() - 1; i >= 0; i -- ){
int d = nums[i]; //第d位
int left = 0, right = 0, power = 1; //left:d左边的值, right:d右边。 power:多少次方
for (int j = nums.size() - 1; j > i; j -- ) left = left * 10 + nums[j];
for (int j = i - 1; j >= 0; j -- ){
right = right * 10 + nums[j];
power *= 10;
}
if (d == 0) res += left * power; //分3种情况讨论
else if (d == 1) res += left * power + right + 1;
else res += (left + 1) * power;
}
return res;
}
int main(){
int n;
cin >> n;
cout << calc(n) << endl;
return 0;
}
1059 Prime Factors
解析
注意点
不用先把质数筛选出来,可以直接从2开始遍历每一个数,如试2, 3,试4的时候,4不是质数,4必然有小于它的质因子, 这些质因子之前已经被筛完了,所以一定不会被4整除。可以理解为,不是质数会直接跳过。
质数:条件写成i <= n / i,写成 i * i <= n 有的题会错
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
printf("%d=", n);
if (n == 1) puts("1");
else{
bool is_first = true;
for (int i = 2; i <= n / i; i ++ )
if (n % i == 0){
int k = 0;
while (n % i == 0) n /= i, k ++ ;
if (!is_first) cout << '*';
else is_first = false;
cout << i;
if (k > 1) cout << "^" << k;
}
if (n > 1){
if (!is_first) cout << '*';
cout << n;
}
}
return 0;
}
1081 Rational Sum
单词:
numerator 分子
denominator 分母
解析
分数的运算
注意点
根据题目给的边界数据来考虑。
只有1,2个点没过,一般是数组越界或整数溢出
#include <iostream>
using namespace std;
typedef long long LL;
//辗转相除法模板,找最大公约数
LL gcd(LL a, LL b){
return b ? gcd(b, a % b) : a;
}
int main(){
LL a = 0, b = 1; //a存分子的和, b存分母的和
int n;
cin >> n;
for (int i = 0; i < n; i ++ ){
LL c, d;
scanf("%lld/%lld", &c, &d);
LL t = gcd(c, d);
c /= t, d /= t;
t = gcd(b, d); //通分的时候,分母通分成最小公倍数
a = d / t * a + b / t * c;
b = b / t * d;
t = gcd(a, b); //多约分,以免超出数据范围
a /= t, b /= t;
}
if (b == 1) cout << a;
else{
if (a >= b) printf("%lld ", a / b), a %= b;
printf("%lld/%lld", a, b);
}
return 0;
}
1088 Rational Arithmetic
解析
分数的运算,简单模拟就行
输出比较麻烦
注意点
数据比较小,不用经常约分
#include <iostream>
using namespace std;
typedef long long LL;
LL gcd(LL a, LL b){ //求最大公约数
return b ? gcd(b, a % b) : a;
}
void print(LL a, LL b){
LL d = gcd(a, b);
a /= d, b /= d;
if (b < 0) a *= -1, b *= -1;
bool is_minus = a < 0;
if (is_minus) cout << "(";
if (b == 1) cout << a;
else{
if (abs(a) >= b) printf("%lld ", a / b), a = abs(a) % b;
printf("%lld/%lld", a, b);
}
if (is_minus) cout << ")";
}
void add(LL a, LL b, LL c, LL d){
print(a, b), cout << " + ", print(c, d), cout << " = ";
a = a * d + b * c;
b = b * d;
print(a, b), cout << endl;
}
void sub(LL a, LL b, LL c, LL d){
print(a, b), cout << " - ", print(c, d), cout << " = ";
a = a * d - b * c;
b = b * d;
print(a, b), cout << endl;
}
void mul(LL a, LL b, LL c, LL d){
print(a, b), cout << " * ", print(c, d), cout << " = ";
a = a * c;
b = b * d;
print(a, b), cout << endl;
}
void div(LL a, LL b, LL c, LL d){
print(a, b), cout << " / ", print(c, d), cout << " = ";
if (!c) puts("Inf");
else{
a = a * d;
b = b * c;
print(a, b), cout << endl;
}
}
int main(){
LL a, b, c, d;
scanf("%lld/%lld %lld/%lld", &a, &b, &c, &d);
add(a, b, c, d);
sub(a, b, c, d);
mul(a, b, c, d);
div(a, b, c, d);
return 0;
}
1096 Consecutive Factors
解析
1.枚举起始位置 k
2.枚举长度
注意点
#include <iostream>
#include <vector>
using namespace std;
int main(){
int n;
cin >> n;
vector<int> res;
for (int i = 2; i <= n / i; i ++ )
if (n % i == 0){
vector<int> seq;
for (int m = n, j = i; m % j == 0; j ++ ){
seq.push_back(j);
m /= j;
}
if (seq.size() > res.size()) res = seq;
}
if (res.empty()) res.push_back(n);
cout << res.size() << endl;
cout << res[0];
for (int i = 1; i < res.size(); i ++ ) cout << '*' << res[i];
return 0;
}
1103 Integer Factorization
解析
注意点
1104 Sum of Number Segments
解析
注意点
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
long double res = 0;
for (int i = 1; i <= n; i ++ ){
long double x;
cin >> x;
res += x * i * (n - i + 1);
}
printf("%.2Lf", res);
return 0;
}