AtCoder Beginner Contest 233题解
A - 10yen Stamp
【题目链接】A - 10yen Stamp (atcoder.jp)
题意:当前数每次可以加10,问至少要加几次才能寄信
- x > y:说明足够寄送了
- x < y:不能送,则加10,知道x > y为止,计数即可。
【代码实现】
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <string.h>
#include <unordered_set>
#include <unordered_map>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
int main()
{
int x, y;
cin >> x >> y;
if(x >= y) cout << 0;
else
{
int ans = 0;
while(x < y)
{
x += 10;
ans ++;
}
cout << ans;
}
return 0;
}
B - A Revers
【题目链接】B - A Reverse (atcoder.jp)
题意:将字符串s在[l,r]的字串翻转后,输出s
知识点:字符串模拟
【代码实现】
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <string.h>
#include <unordered_set>
#include <unordered_map>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 1e5 + 10;
char s[N];
int main()
{
int l, r;
scanf("%d%d", &l, &r);
scanf("%s", s + 1);
int len = strlen(s + 1);
//双指针实现翻转
int i = l, j = r;
while(i < j) swap(s[i ++], s[j --]);
printf("%s", s + 1);
return 0;
}
C - Product
【题目链接】C - Product (atcoder.jp)
题意:有n个包,每个包里有若干带数字的球,让你每个包里面选一个球使得数字乘积为x,最后让你求满足等于x的方案数。
注:
- 数据的范围
- 剪枝
知识点:DFS
【代码实现】
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <string.h>
#include <unordered_set>
#include <unordered_map>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 1e5 + 10;
int n, res = 0;
LL target;
vector<LL> a[N];// 二维数组
void dfs(int u, LL val)//选择到了第几个背包 现在背包的重量是多少
{
if(u == n)
{
if(val == target) res ++;
return ;
}
for(int j = 0; j < a[u].size(); j ++)// 用vector做的二维数组,每一层调用.size(),即可得到当前层的背包的个数
{
if(a[u][j] * val > target) continue;// 剪枝
dfs(u + 1, val * a[u][j]);
}
}
int main()
{
scanf("%d%lld", &n, &target);
for(int i = 0; i < n; i ++)
{
int cnt;
scanf("%d", &cnt);
for(int j = 0; j < cnt; j ++)
{
LL value;
scanf("%lld", &value);
a[i].push_back(value);
}
}
dfs(0, 1);
printf("%d", res);
return 0;
}
D - Count Interval
【题目链接】D - Count Interval (atcoder.jp)
题意:统计s[r]-s[l - 1] == k
出现的次数
思路:如果枚举区间的话,时间复杂度会爆炸,统计s[r]-s[l - 1] == k
等价于统计s[r]-k == s[l - 1]
。然后对于每个r只需要求下 s[r]-k的个数,也就是s[l-1]的个数。s[l-1]也是个前缀和,所以循环的时候顺便把前缀和个数自增 。(枚举右端点求s[r]-k == s[l - 1]的次数,只不过我们在计数前缀和时同时预处理出来了s[l-1]的值,因为它也是个前缀和的值!)
知识点:前缀和 + 哈希表
【代码实现】
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <string.h>
#include <unordered_set>
#include <unordered_map>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 2e5 + 10;
LL s[N];
int main()
{
LL n, k, res = 0;
scanf("%lld%lld", &n, &k);
unordered_map<LL, LL> hasp;
for(int i = 1; i <= n; i ++)
{
scanf("%lld", &s[i]);
s[i] = s[i] + s[i - 1];
hasp[s[i - 1]] ++;
res += hasp[s[i] - k];
}
printf("%lld", res);
return 0;
}