练习赛02
A - 10yen Stamp
判断是x和y的差值是10的多少倍。向上取整,注意小于0的情况
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
#include<map>
#define ll long long
using namespace std;
int main() {
int x, y;
cin >> x >> y;
int num = y - x;
if(num<0) num = 0;
int res = num / 10;
if(num % 10 != 0) res++;
cout << res << endl;
return 0;
}
B - A Reverse
将字符串中的某一段翻转,实现方法很多。
这里写出一种最常见的。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main(){
string s;
int l, r;
cin >> l >> r;
cin >> s;
int len = s.length();
s = " " + s;
string res = "";
for(int i=1; i<=l-1; i++){
res += s[i];
}
for(int i=r; i>=l; i--){
res += s[i];
}
for(int i=r+1; i<=len; i++){
res += s[i];
}
cout << res << endl;
return 0;
}
C - Product
在N行的每一行中选一个数,使他们的乘积等于X。
这个使用搜索去枚举每一种选数情况。
有一个小剪枝:当乘积大于X的时候就终止这一次的搜索。
#include<bits/stdc++.h>
#include<vector>
#include<cstring>
#define ll long long
using namespace std;
vector<vector<ll>> v;
ll n;
ll x, res;
void dfs(ll pos, ll mul) {
//pos:开始行,mul:乘积
if(pos == n) { //结束
if(mul == x) res++;
return;
}
for(auto i: v[pos]) { // 去枚举这一行中每一个数
if(mul * i > x) continue; // 剪枝
dfs(pos+1, i*mul); // 寻找下一行中的数
}
}
int main() {
cin >> n >> x;
v.resize(n); //重新定义大小
for(ll i=0; i<n; i++) {
int num;
cin >> num;
v[i].resize(num); //重定义大小
for(ll j=0; j<num; j++) {
cin >> v[i][j];
}
dfs(0, 1);
}
cout << res << endl;
return 0;
}
D - Count Interval
计算数组中有多少连续的子序列的和等于k
每个子序列的和我们可以通过求前缀和来获得。
eg:
[
l
,
r
]
=
s
u
m
[
r
]
−
s
u
m
[
l
−
1
]
,
s
u
m
[
i
]
表
示
前
i
个
数
的
和
[l,r]=sum[r]-sum[l-1],sum[i]表示前i个数的和
[l,r]=sum[r]−sum[l−1],sum[i]表示前i个数的和
那么我们记录每一个前缀和出现的次数然后判断
s
u
m
−
k
sum-k
sum−k出现的次数即为子序列的和等于
k
k
k的
l
,
r
l,r
l,r的对数。
#include<bits/stdc++.h>
#include<vector>
#include<cstring>
#define ll long long
using namespace std;
int main() {
ll n, k;
cin >> n >> k;
ll sum = 0;
map<ll, int> mp;
mp[0] = 1;
ll res = 0;
for(int i=1; i<=n; i++){
ll num;
cin >> num;
sum += num;//前i个数的和
res += mp[sum-k];
mp[sum]++; // 记录次数
}
cout << res << endl;
return 0;
}
E - Σ[k=0…10100]floor(X/10k)
公式化简过来其实就是每次去掉最后一位的数相加的和。
列个竖式很明显找到规律:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
#include<map>
#define ll long long
using namespace std;
vector<int> v;
int main(){
string s;
cin >> s;
int len = s.size();
//所有数字之和
int sum = 0;
for(int i=0; i<len; i++) sum += s[i] - '0';
int tmp = 0;
for(int i=len-1; i>=0; i--){
tmp += sum;
int num = tmp % 10; // 该位
v.push_back(num);
tmp /= 10; // 进位
sum -= (s[i] - '0');//去掉最后一个数
}
if(tmp != 0) v.push_back(tmp);
while(!v.empty()){
cout << v.back();
v.pop_back();
}
return 0;
}