栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

2020年蓝桥杯国赛C++B组试题(临时抱佛脚)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2020年蓝桥杯国赛C++B组试题(临时抱佛脚)

目录
      •  一 扩散——广度优先搜索
      •  二 阶乘约数——数论
      •  三 本质上升序列——动态规划
      •  四 玩具蛇——DFS

 一 扩散——广度优先搜索

题目链接


注意坐标可能是负数就可以了,因此,我们把初始点整体右移一定距离,然后常规BFS。

#include
using namespace std;
string s11,s22 ,s1 ,s2;
int N = 3000;
int a[8000][8000];
int times[8000][8000];
typedef pair P;
P beg,cur,next,end;
queue

Q; int dir[4][2] = { {1,0},{0,1},{-1,0},{0,-1}}; int main(){ a[N][N] = 1; a[2020+N][11+N] = 1; a[11+N][14+N] = 1; a[2000+N][2000+N] = 1; beg.first = N;beg.second = N; Q.push(beg); beg.first = 2020+N;beg.second = 11+N; Q.push(beg); beg.first = 11+N;beg.second = 14+N; Q.push(beg); beg.first = 2000+N;beg.second = 2000+N; Q.push(beg); int tx, ty; while(!Q.empty()){ cur= Q.front();Q.pop(); if(times[cur.first][cur.second] == 2020){ break; } for(int i = 0 ; i < 4; ++i){ tx = cur.first + dir[i][0]; ty = cur.second + dir[i][1]; if(a[tx][ty] == 1){ continue; } else{ times[tx][ty] = times[cur.first][cur.second] + 1; a[tx][ty] = 1; next.first = tx; next.second = ty; Q.push(next); } } } int ans = 0; for(int i = 0 ; i < 8000; ++i){ for(int j = 0 ; j < 8000; ++j){ if(a[i][j]){ ans++; } } } cout<  二 阶乘约数——数论

题目链接

思路

根据数论知识:任意一个正整数都可以写成若干质数的乘积,X = p1^α1 * p2^ α2 …… * pk^αk
那么约数的个数p = (α1+1)*(α2 +1)*…*(αk +1)
有了上述基础,那么n!的约数个数也就是先把n!转为若干质数的乘积,并统计每一个质数的个数,然后根据公式求得约数个数即可。

#include
using namespace std;
#define int long long 
map m;
signed main(){
	//统计n个数的若干质数乘积。 
	for(int i = 2; i <=100;++i){
		int t = i;
		//统计每一个数t的若干质数乘积 
		for(int j = 2 ; j <= t ;){
			if(t % j == 0){
				t = t / j;
				m[j] ++; 
			}else{
				j ++;
			}
		}	
	}
	map::iterator it = m. begin();
	//根据公式求得约数。
	int ans = 1; 
	for(;it!=m.end();++it){
		ans = ans*(it->second+1);
	}
	cout< 
 三 本质上升序列——动态规划 

题目链接

思路
据说90%的字符串问题都可以用 动态规划(dp) 解决哦

动态规划三大步, 1.设状态表示方程 2.找状态转移方程 3.状态方程初始化
dp 思路:题目要求去重递增子序列的个数,不妨拆开来做,即先求递增子序列的个数,再考虑去重。
1.假设dp[i]表示前i个的递增子序列的个数(通常为题目所求结果即为状态表示方程)
2. 由于是递增子序列,那么 需满足前提 dp[i] > dp[j],有 dp[i] = dp[i] + dp[j]。 显然j < i。
3.因为每一个str[i]是一个递增子序列,那么初始化 dp[i] = 1;

现在考虑去重,在第2个中的状态转移方程中,我们只考虑了dp[i] > dp[j]的情形,那么如果dp[i] == dp[j]和dp[i]

  1. 对于dp[i] < dp[j],不符合题意,continue掉;
  2. 对于dp[i] == dp[j],说明此时有两个字符是相同的,那么dp[j]与dp[j]前面的子序列组成的情况 和 dp[i]与dp[j]前面子序列组成的情况必然会出现重复统计,例如 a n n,dp[0] = 1 dp[1] = 3 dp[2] = 3 ,这里重复统计了一次an的递增子序列,即a、 n、 an ,所以有dp[i] = dp[i] - dp[j]。

因此,总的状态转移为:

 if(str[i] > str[j]){
 	dp[i] = dp[i] + dp[j]; 
} else if(str[i] == str[j]){
	dp[i] = dp[i] - dp[j]; 
}
#include
using namespace std;
#define int long long 
set sets;

string str;
string s;
// 共有2的200次方种方案, 铁定超时,所以下面用dp做。 
void dfs(int i){
	if(i >= str.size()){
		sets.insert(s);
		return;
	}
	if(str[i] > s[s.size()-1]){  //可选 
		s+=str[i];
		dfs(i+1);
		s.erase(s.size()-1);
	}
	dfs(i+1);  //不选 
}
int dp[1000];
signed main(){
	str = "tocyjkdzcieoiodfpbgcncsrjbhmugdnojjddhllnofawllbhfiadgdcdjstemphmnjihecoapdjjrprrqnhgccevdarufmliqijgihhfgdcmxvicfauachlifhafpdccfseflcdgjncadfclvfmadvrnaaahahndsikzssoywakgnfjjaihtniptwoulxbaeqkqhfwl";
//	dfs(0);
//	cout<
		dp[i] = 1;  //每个本身有一个。 
		for(int j = 0; j < i; ++j){
			if(str[i] > str[j]){
				dp[i] = dp[i] + dp[j]; 
			} else if(str[i] == str[j]){
				dp[i] = dp[i] - dp[j];  //去重 假如有 a n n ,那么dp[1] = 3, dp[2] = 3 因此是重复统计了一次an的子序列,即a n an 
			}
		}
	} 
	int ans = 0;
	for(int i = 0 ;i < str.size();++i) ans += dp[i];
	cout< 
 四 玩具蛇——DFS 

题目链接

确定了一个位置后,下一个位置可能的情况就知道了,这就可以用深度优先搜索来做。题目的意思就是要求1-16依次连续放入方格中的方案数量。

#include
using namespace std;
int dir[4][2] = { {0,1}, {1,0},{-1,0},{0,-1}};
int vis[10][10];
int cnt;
int k;
void dfs(int x, int y){
	if(k == 16){
		cnt ++;
//		for(int i = 1; i <= 4; ++i){
//			for(int j = 1; j <= 4; ++j){
//				cout<
		int tx = x + dir[i][0]; 
		int ty = y+dir[i][1];
		if(tx>=1 &&tx <= 4 && ty >= 1 && ty <= 4 && vis[tx][ty] == 0){
			k++;
			vis[tx][ty] = k; 
			dfs(tx, ty);
			k--;
			vis[tx][ty] = 0;
		}
	}
}

int main(){
	for(int i = 1; i <= 4; ++i){
		for(int j = 1; j <= 4; ++j){
			k = 1;
			vis[i][j] = 1;
			dfs(i,j);
			vis[i][j] = 0;
		}
	}
	cout<
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/977315.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号