蓝桥杯练习系统【不完全刷题记录】

等到做真题的时候再上蓝桥杯的练习系统吧,还是转战洛谷。


基础练习

十六进制转八进制1:

#include 
#include 
#include 
using namespace std;

long long pow(long long x, long long y) {
	long long ans = 1;
	while (y > 0) {
		if (y & 1) {
			ans *= x;
		}
		x *= x;
		y >>= 1;
	}
	return ans;
}

int main() {
	int t;
	cin >> t;
	string s1, s2;
	long long n;
	while (t--) {
		cin >> s1;
		s2 = "";
		n = 0;
		for (int i = 0; i < s1.size(); i++) {
			if (s1[i] <= '9' && s1[i] >= '0') {
				n += (s1[i] - '0') * pow(16, s1.size() - i - 1);
			} else {
				n += (s1[i] - 'A' + 10) * pow(16, s1.size() - i - 1);
			}
		}
		int a, b;
		while (n) {
			a = n % 8;
			s2 += (a + '0');
			n /= 8;
		}
		for (int i = s2.size() - 1; i >= 0; i--) {
			cout << s2[i];
		}
		cout << endl;
	}
	return 0;
}

十六进制转八进制2:

#include
using namespace std;

//思路:100000位的十六进制数,这么大的数不好直接处理,以二进制字符串转换为八进制即可 
int main(){
	int n;
	cin>>n;
	while(n--){
		string s;
		cin>>s;
		
		int len1 = s.length();
		string res1="";
		//将16进制转换为二进制字符串 
		for (int i=0;i

特殊回文数:枚举暴力+小优化

#include 
using namespace std;

//枚举暴力+小优化
int main() {
	int n;
	cin >> n;
	//枚举五位数
	for (int i = 1; i <= 9; i++) {
		for (int j = 0; j <= 9; j++) {
			for (int k = 0; k <= 9; k++) {
				if (i * 2 + j * 2 + k == n) {
					cout << i * 10000 + j * 1000 + k * 100 + j * 10 + i << endl;
				}
			}
		}
	}
	//枚举六位数
	for (int i = 1; i <= 9; i++) {
		for (int j = 0; j <= 9; j++) {
			for (int k = 0; k <= 9; k++) {
				if (i * 2 + j * 2 + k * 2 == n) {
					cout << i * 100000 + j * 10000 + k * 1000 + k * 100 + j * 10 + i << endl;
				}
			}
		}
	}
	return 0;
}

算法训练:

1、动态规划

告别动态规划,连刷40道动规算法题,我总结了动规的套路 - 云+社区 - 腾讯云 (tencent.com)

例1:印章(见收藏) 

背包问题:01背包 、完全背包

咱就把0-1背包问题讲个通透! - 知乎 (zhihu.com)

动态规划---完全背包问题详解 - DarkerG - 博客园 (cnblogs.com)

2、搜索

例1:数字游戏

#include 
#include 
#include 
using namespace std;
int a[20], b[20][20];

int main() {
	int n, sum;
	cin >> n >> sum;
	for (int i = 1; i <= n; i++) {
		a[i] = i;
	}
	do {
		memset(b, 0, sizeof(b));
		for (int i = 1; i <= n; i++) {
			b[1][i] = a[i];
		}
		for (int i = 2; i <= n; i++) {
			for (int j = 1; j <= n - i + 1; j++) {
				b[i][j] = b[i - 1][j] + b[i - 1][j + 1];
			}
		}
		if (b[n][1] == sum) {
			for (int i = 1; i <= n; i++) {
				cout << a[i] << ' ';
			}
			break;
		}
	} while (next_permutation(a + 1, a + 1 + n));
	return 0;
}

 例2:无聊的逗(状态搜索)

#include 
#include 
using namespace std;
int a[20];

int main() {
	int n, sum = 0, sum1 = 0;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
		sum += a[i];
	}
	sort(a, a + n);
	sum1 = sum / 2;
	int ans = 0;
	for (int i = n - 1; i >= 0; i--) {
		if (ans + a[i] <= sum1) {
			ans += a[i];
		}
	}
	cout << ans;
	return 0;
}

例3:跳马(剪枝)

#include 
using namespace std;
int m[10][10];
bool vis[10][10];

int dx[8] = {1, 1, -1, -1, 2, 2, -2, -2};

int dy[8] = {2, -2, 2, -2, 1, -1, 1, -1};
int a, b, c, d, cnt, ans = -1;

void dfs(int i, int j) {
	if (ans != -1 && ans < cnt) {
		return;
	}
	if (i == c && j == d) {
		ans = cnt;
		return;
	}
	for (int k = 0; k < 8; k++) {
		if (i + dx[k] > 0 && i + dx[k] <= 8 && j + dy[k] > 0 && j + dy[k] <= 8 && vis[i + dx[k]][j + dy[k]] == 0) {
			cnt++;
			vis[i + dx[k]][j + dy[k]] = 1;
			dfs(i + dx[k], j + dy[k]);
			vis[i + dx[k]][j + dy[k]] = 0;
			cnt--;
		}
	}
}

int main() {
	cin >> a >> b >> c >> d;
	vis[a][b] = 1;
	dfs(a, b);
	cout << ans;
	return 0;
}

3、二分

例1:礼物

#include 
using namespace std;
long long a[1000010], val[1000010];
long long n, s;

bool check(int mid) {
	for (int i = mid; i <= n - mid; i++) {
		if (val[i] - val[i - mid] <= s && val[i + mid] - val[i] <= s) {
			return true;
		}
	}
	return false;
}

int main() {
	cin >> n >> s;
	for (int i = 1; i <= n; i++) {
		scanf("%lld", &a[i]);
		val[i] = val[i - 1] + a[i];
	}
	int l = 1, r = n;
	while (l < r) {
		int mid = (l + r + 1) >> 1;
		if (check(mid)) {
			l = mid;
		} else {
			r = mid - 1;
		}
	}
	cout << l * 2;
	return 0;
}

4、递推

例1:过河马

dfs超时:

#include 
#define mod 1000000007
using namespace std;
long long cnt, m, n;
bool vis[105][105];

int dy[4] = {1, 2, -1, -2};

int dx[4] = {2, 1, 2, 1};

void dfs(int x, int y) {
	if (x == n && y == m) {
		cnt = (cnt + 1) % mod;
		return;
	}
	for (int i = 0; i < 4; i++) {
		int xx = x + dx[i];
		int yy = y + dy[i];
		if (xx <= n && xx >= 1 && yy <= m && yy >= 1 && vis[xx][yy] == 0) {
			vis[xx][yy] = 1;
			dfs(xx, yy);
			vis[xx][yy] = 0;
		}
	}
}

int main() {
	cin >> n >> m;
	vis[1][1] = 1;
	dfs(1, 1);
	cout << cnt;
	return 0;
}

 数组递推:

#include 
#define mod 1000000007
using namespace std;
long long dp[105][105];

int dy[4] = {1, 2, -1, -2};

int dx[4] = {2, 1, 2, 1};

int main() {
	int n, m;
	cin >> n >> m;
	dp[2][3] = dp[3][2] = 1;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			for (int k = 0; k < 4; k++) {
				int x = i + dx[k];
				int y = j + dy[k];
				if (x >= 1 && x <= n && y >= 1 && y <= m) {
					dp[x][y] = (dp[i][j] + dp[x][y]) % mod;
				}
			}
		}
	}
	cout << dp[n][m];
	return 0;
}

例2:斐波那契串(找规律)

#include 
#include 
using namespace std;
string s0 = "0", s1 = "1", s, sub;
long long n, ans, cnt1, cnt2;

int main() {
	cin >> n;
	cin >> sub;
	for (int i = 2; i <= 20; i++) {
		s = s1 + s0;
		s0 = s1;
		s1 = s;
	}
	for (int i = 0; i <= s.size() - sub.size(); i++) {
		if (sub == s.substr(i, sub.size())) {
			cnt1++;
		}
	}
	s = s1 + s0;
	s0 = s1;
	s1 = s;
	for (int i = 0; i <= s.size() - sub.size(); i++) {
		if (sub == s.substr(i, sub.size())) {
			cnt2++;
		}
	}
	for (int i = 22; i <= n; i++) {
		ans = cnt1 + cnt2 + 1;
		cnt1 = cnt2;
		cnt2 = ans;
	}
	cout << ans;
	return 0;
}

5、字符串

例1:预备爷的悲剧

map:

#include 
#include 
#include 
using namespace std;
mapt1, t2;
int a[100010];

int main() {
	int n, m, p, ans = 0;
	string s;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> s >> p;
		t1[s]++;
		if (t1[s] == 1) {
			t2[s] = p;
		} else if (t1[s] > 1 && t2[s] > p) {
			t2[s] = p;
		}
	}
	cin >> m;
	for (int i = 0; i < m; i++) {
		cin >> s;
		a[t2[s]]++;
		if (a[t2[s]] == 1) {
			ans++;
		}
	}
	cout << ans;
	return 0;
}

6、贪心

例1:藏匿的刺客

#include 
#include 
#include 
using namespace std;

class Intvl {
	public:
		int l;
		int r;
};

bool cmp(Intvl a, Intvl b) {
	return a.r < b.r;
}

int main() {
	int n, ans = 1;
	cin >> n;
	vectorv(n);
	for (int i = 0; i < n; i++) {
		cin >> v[i].l >> v[i].r;
	}
	sort(v.begin(), v.end(), cmp);
	int minn = v[0].r;
	for (int i = 1; i < n; i++) {
		if (v[i].l > minn) {
			ans++;
			minn = v[i].r;
		}
	}
	cout << ans;
	return 0;
}

7、模拟

例1:循环矩阵乘法(暴力模拟只有60分,超时了,不知道怎么优化)

#include 
using namespace std;
int n, q, a[5010][5010], qi[110], ans[5010];

int main() {
	cin >> n >> q;
	for (int i = 0; i < q; i++) {
		scanf("%d", &qi[i]);
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			scanf("%d", &a[i][j]);
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			ans[i] += a[0][j] * a[j][i];
		}
	}
	for (int i = 0; i < q; i++) {
		int cnt = 0;
		if (qi[i] == 0) {
			for (int j = 0; j < n; j++) {
				printf("%d ", ans[j]);
			}
			cout << endl;
		} else {
			for (int j = n - qi[i]; cnt < n; cnt++) {
				printf("%d ", ans[j]);
				j++;
				j %= n;
			}
			cout << endl;
		}
	}
	return 0;
}

你可能感兴趣的:(蓝桥杯,c++,算法)