题目链接
普及题:
http://acm.zzuli.edu.cn/problem.php?id=2427
提高题:
http://acm.zzuli.edu.cn/problem.php?id=2525
普及题
2427: 二进制加法
一个思路是模拟二进制的加法,用字符串储存两个数,从末位数开始加,如果位数之和大于2就进位。最后得到一个相加的字符串。代码如下:
add函数可以作为任何进制相加的模板。当然使用java中BigInteger类和String类中的相关方法也能解决本题。
#include<bits/stdc++.h>
using namespace std;
//b: b进制下的加法
string add(string str1, string str2, int b){
string ans = "";
int l1 = str1.size()-1;
int l2 = str2.size()-1;
int n, n1, n2, sign = 0;
while(l1 >= 0 || l2 >= 0){
if(l1 >= 0)
n1 = str1[l1] - '0';
else n1 = 0;
if(l2 >= 0)
n2 = str2[l2] - '0';
else n2 = 0;
n = n1 + n2 + sign;
sign = n / b;
n = n % b;
ans = ans + char(n + '0');
l1--; l2--;
}
if(sign)
ans = ans + char(sign + '0');
//得到的字符串是反的,需要翻转一下
reverse(ans.begin(), ans.end());
return ans;
}
int main(){
int t;
string str1, str2;
cin >> t;
while(t--){
cin >> str1 >> str2;
cout << add(str1, str2, 2) << endl;
}
}
提高题
2425: 青蛙抓虫
这类题之前遇到很多次了。
比如有一次周赛的题:
http://acm.zzuli.edu.cn/problem.php?id=2745
解析:https://blog.csdn.net/qq_45874814/article/details/111185391
思路简单说就是:
青蛙跳到M位置的方式是 跳到M-1,M-2,…,M-N位置方式之和。
假设N=2时,青蛙想要跳到位置3时,一定是从位置1处或者位置2处跳到位置3的,因为他每次最多只能跳两格,那么跳到位置3的方式数就是跳到位置2处方式数与跳到位置1处方式数之和。
以此类推便能找到规律。代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 1e9+7;
int dp[1005];
int main(){
int t, m, n;
cin >> t;
while(t--){
cin >> m >> n;
LL ans = 0;
memset(dp, 0, sizeof(dp));
dp[0] = 1;
for(int i = 1; i <= m; i++){
LL c = 0;
for(int j = 1; j <= n; j++){
if(i-j >= 0)
c = (c+dp[i-j]) % mod;
}
dp[i] = c;
}
cout << dp[m] << endl;
}
}
dp[i]的值,就是dp[i]之前n项的和,发现这个后,就可以用前缀和来优化一下代码,每次只需要减去第i-n-1项,加上第i-1项即可,时间复杂度会更低。代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 1e9+7;
int dp[1005];
int main(){
int t, m, n;
cin >> t;
while(t--){
scanf("%d %d",&m, &n);
LL ans = 0;
memset(dp, 0, sizeof(dp));
dp[0] = 1;
for(int i = 1; i <= m; i++){
if(i - n - 1 >= 0){
ans = ans + mod - dp[i-n-1];
}
ans = (ans + dp[i-1]) % mod;
dp[i] = ans;
}
cout << ans << endl;
}
}