回溯、取模、日期计算

C++回溯

1、回溯常见模板

/*
	回溯法模板
	def func():
		if 满足条件:
			return result
		for range 选择列表:
			选择
			func()
			撤销选择 
*/ 

代码示例:1.求1~n的全排列并打印出来。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+5;
int n;
int a[N],vis[N];
void dfs(int dep){
	if(dep==n+1){
		for(int i=1;i<=n;i++){
			cout<<a[i]<<" \n"[i==n];
		}
		return;
	}
	for(int i=1;i<=n;i++){
		if(vis[i])continue;
		vis[i]=1;//
		a[dep]=i;
		dfs(dep+1);
		vis[i]=0;//
	}
	
}
int main(){
	ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
 	cin>>n;
 	dfs(1);
	return 0;
}

也可以使用库函数next_permutaition():

#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+5;
int main(){
	ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
 	int n;cin>>n;
 	vector<int> a(n);
 	for(int i=1;i<=n;i++){
 		a[i-1]=i;
	 }
 	do{
 		for(int i=0;i<n;i++)cout<<a[i]<<" \n"[i==n-1];
	}while(next_permutation(a.begin(),a.end()));	
	return 0;
}

2、取每位数的模

def isNmp:
	while(x):
		 t=x%10;
		 if 正确
		 	return true
		 x/=10;
return false

3、回文日期

  1. int year = j % 10 * 1000 + (j / 10) * 100 + i % 10 * 10 + i / 10;

    • 这行代码是将给定的月份 i 和天数 j 转换为一个四位数的年份。类似于之前,j 被分成十位和个位,然后乘以相应的权重,而 i 也类似地处理,确保每个数字都在正确的位置上。最后,将它们加起来形成一个四位数的年份。
  2. int sum = year * 10000 + i * 100 + j;

    • 这行代码是将年份、月份和日期合并成一个整数表示一个完整的日期。年份乘以 10000 是为了把它移到正确的位置,月份乘以 100 是为了把它移到正确的位置,最后把日期直接加到末尾即可。
#include<bits/stdc++.h>
using namespace std;
int main(){
	ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
	// 1   2  3   4   5   6   7   8   9   10   11   12 
	// 31     31  30  31  30  31  31  30  31   30   31
	// 判断2月是否是闰年 =>  return x%400==0 || (x%4==0 && x%100!=0)
	// 闰年 29天 ,平年 28天
	int y[]={0,31,29,31,30,31,30,31,31,30,31,30,31};
	int n,m;cin>>n>>m;
	int ans=0;
	for(int i=1;i<=12;i++){
		for(int j=1;j<=y[i];j++){
			int year=j%10*1000+(j/10)*100+i%10*10+i/10;
			int sum=year*10000+i*100+j;
			if(sum>m||sum<n)continue;
			else ans++;
		}
	}
	cout<<ans;
	return 0;
}
  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
回溯法马步遍历问题的复杂度分析需要考虑以下几个因素: 1. 棋盘的大小:设棋盘大小为 $n \times m$,则遍历问题的规模为 $nm$。 2. 起始位置的选择:由于马的走法具有对称性,因此可以假设起始位置为 $(0, 0)$,并对其它起始位置进行对称处理。这样可以减少起始位置的选择,但并不会影响问题的复杂度。 3. 马的走法:每个格子可以选择的下一个格子最多有 $8$ 个,因此每个格子最多需要尝试 $8$ 次才能找到一个可行的下一个格子。 4. 剪枝优化:在实际的实现中,可以使用一些剪枝优化来减少回溯的次数,例如可以按照下一个格子能够到达的未访问过的格子数量从小到大进行排序,这样可以优先选择能够到达较少未访问过的格子的下一个格子。 根据以上因素,回溯法马步遍历问题的复杂度可以分析如下: - 时间复杂度:设棋盘大小为 $n \times m$,则回溯法马步遍历问题的时间复杂度为 $O(8^{nm})$,因为每个格子最多需要尝试 $8$ 次才能找到一个可行的下一个格子,而遍历所有格子需要尝试的次数是指数级别的。 - 空间复杂度:回溯法马步遍历问题的空间复杂度取决于递归调用栈的深度,即最多需要保存 $nm$ 个格子的信息。因此空间复杂度为 $O(nm)$。 需要注意的是,由于回溯法马步遍历问题的时间复杂度是指数级别的,因此对于较大的棋盘来说,回溯法是无法在合理的时间内得到解决的。在实际应用中,需要考虑使用其它更加高效的算法来解决马步遍历问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

席万里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值