第十五届蓝桥杯省赛C/C++大学B组自己的想法

第一次参加蓝桥杯,不知道自己能不能有个奖。在Acwing、codeforces、蓝桥杯官网均有刷题(不多)。只会一些基础算法,希望发布自己的想法,通过大佬们的指导,得到提高(代码比较水希望别骂)。

第十五届蓝桥杯省赛C/C++ 组真题

握手问题

分析:

第一题既是签到题,又是最搞心态的题。就是两两握手,例如:A 与 B握手和B 与 A握手只计算一次,由于无序所以用组合数知识

题目:

8a558d6cb363479c89b64dc7ba721d91.png

结果:

33df7cc933904768892ae77a06935116.png

小球反弹

分析:

这个题比赛没有写出来。运用高中知识分解成x,y轴的反复运动。

题目:5632990d32264bc68a9fd7a7244c6eee.png

84da4f82b8c041fda59d061408ee526f.png

结果:

然后解出 t ,最后的答案就是sqrt(15 * 15 + 17 * 17) * t == 1100325199.77  (保留2位小数的结果)

好数

分析:

我做题习惯先从数据大小下手。1e7数据暴力用循环,时间复杂度为(O(7n)),1s能过。

代码演示:

#include <bits/stdc++.h>
using namespace std;

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n;
	cin >> n;
	int res = 0;
	for(int i = 1;i <= n;i++) //1 ~ n个数 
	{
		bool flag = true;
		int val = i , t = 1;
		while(val)
		{
			if(t && val % 2 == 0) //如果当前是奇数位并且尾数是偶数 
			{
				flag = false;
				break;
			}
			else if(!t && val % 2 != 0)  //如果当前是偶数位并且尾数是奇数
			{
				flag = false;
				break;
			}
			t++;
			t %= 2;  //t为1时代表当前为奇数位,0为偶数位 
			val /= 10;
		}
		if(flag)res++; //如果是好数 
	}
	cout << res;
	return 0;
}

R 格式

分析:

比赛的时候我用的乘法的高精度和加法高精度

代码演示:

#include <bits/stdc++.h>
using namespace std;
int dis;

vector<int> add(vector<int> &A)  //加法高精度
{
	int t = 1;
	for(int i = dis + 1;i < A.size();i++)
	{
		t += A[i];
		A[i] = t % 10;
		t /= 10;
	}
	if(t)A.push_back(t);
	return A;
}

vector<int> mul(vector<int> &A , int n)  //乘法高精度
{
	for(int i = 0; i < n;i++)  //2的n次方
	{
		int t = 0;
		for(int j = 0;j < A.size();j++)
		{
			if(A[j] != 10)
			{
				t += A[j] * 2;
				A[j] = t % 10;
				t /= 10;
			}
			else dis = j;
		}
		if(t)A.push_back(t);
	}
	if(A[dis - 1] >= 5)A = add(A);
	return A;
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n;
	string a;
	cin >> n >> a;
	vector<int> A;
	for(int i = a.size() - 1;i >= 0;i--)
	{
		if(a[i] == '.')A.push_back(10);
		else A.push_back(a[i] - '0');
	}
	vector<int> C = mul(A , n);
	for(int i = C.size() - 1;i >= dis + 1;i--)cout << C[i];
	return 0;
}

数子接龙:

分析:

第一反应dfs暴搜,路径注意不交叉就行,我是这样维护交叉的

代码演示:

#include <bits/stdc++.h>
using namespace std;
const int N = 12;
int g[N][N] , kgx[N][N] , kgy[N][N];  //kg记录从那个点来的
bool st[N][N];  //记录这个点是不是走过
int d[N * N] , cnt = 0;  //存放答案的位置
int n , k;

bool dfs(int x , int y , int c)
{
    if(cnt == n * n - 1 && x == n && y == n)return true;
	int fy[8] = {0 , 1 , 1 , 1 , 0 , -1 , -1 , -1} , fx[8] = {-1 , -1 , 0 , 1 , 1 , 1 , 0 , -1};
	for(int i = 0;i < 8;i++)
	{
		int dx = x + fx[i] , dy = y + fy[i];
		int kx1 = kgx[dx][y] , ky1 = kgy[dx][y] , kx2 = kgx[x][dy] , ky2 = kgy[x][dy];
		if(!st[dx][dy] && dx > 0 && dx <= n && dy > 0 && dy <= n && g[dx][dy] == (g[x][y] + 1) % k && (kx1 != x || ky1 != dy) && (kx2 != dx || ky2 != y)) 
        //确保没走过,且要走的点在范围内,要走的点值 == 当前点值加一对k取余,并且不会有交叉
		{
		    st[dx][dy] = true;
		    d[++cnt] = i;
		    kgx[dx][dy] = x , kgy[dx][dy] = y;
		    if(dfs(dx , dy , g[dx][dy]))return true;
		    kgx[dx][dy] = 0 , kgy[dx][dy] = 0;
		    cnt--;
		    st[dx][dy] = false;
		}
	}
	return false;
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> k;
	for(int i = 1;i <= n;i++)
	{
		for(int j = 1;j <= n;j++)
		{
			cin >> g[i][j];
		}
	}
	st[1][1] = true;
	if(dfs(1 , 1 , 0))  //我认为(1,1)这个点一定是0,因为题目说从0开始
	{
		for(int i = 1;i <= n * n - 1;i++)cout << d[i];
	}
	else cout << "-1";  
	return 0;
}

爬山:

分析:

这个题数据有点大如果每次都去找最大值肯定会T的,所以可以考虑使用优先队列优化

代码演示: 

#include <bits/stdc++.h>
using namespace std;

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	priority_queue<int , vector<int> > h;
	int n , p , q;
	cin >> n >> p >> q;
	for(int i = 0;i < n;i++)
	{
		int t;
		cin >> t;
		h.push(t);
	}
	while(p != 0 || q != 0)
	{
		int t = h.top();
		h.pop();
		if(p > 0 && q > 0 && sqrt(t) < t / 2)
		{
			h.push(sqrt(t));
			p--;
		}
		else if(p > 0 && q > 0)
		{
			h.push(t / 2);
			q--;
		}
		else if(p > 0)
		{
			h.push(sqrt(t));
			p--;
		}
		else
		{
			h.push(t / 2);
			q--;
		}
	}
	int res = 0;
	while(h.size())
	{
		int t = h.top();
		h.pop();
		res += t;
	}
	cout << res;
	return 0;
}

总结

感觉现在写的和比赛写的不一样,开始怀疑自己数字接龙问题里的对g[x][y] mod k写成g[x][y] mod 3了,还有宝石组合和拔河比赛没写,我怕随便写也过不了,等加入题库了再补题。以上的代码是我考试的想法不一定能AC,如有不足的地方希望大佬们能多多指导,谢谢大家!

  • 11
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值