人工智能实验室寒假集训-Day6

题目链接

普及题:
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;
	}
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值