2020年第十一届C/C++ A组第二场蓝桥杯省赛

Pro

自行百度搜索就有资源哦

以下只用文字来描述题解,可能不给代码了

主要是因为准备时间有限,没时间一一写代码了

Sol

门牌制作

直接枚举拆分记录2的个数就行

既约分数

枚举1-2020 O(n^2)时间内记录互质的组数

蛇形填数

别的博主可能有旋转的操作什么的,然而我就纯写的模拟,用flag表示填数的方向

大概张下面这样

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
typedef long long LL;
#define PI acos(-1)
#define INF 2147483647
#define eps 1e-7
#define L 100005
#define Fo(i,a,b) for(LL i=(a); i<=(b); i++)
#define Ro(i,b,a) for(LL i=(b); i>=(a); i--)
#define Ms(a,b) memset((a),(b),sizeof(a))
#define _ceil(_,__) (_+(__-1))/__
#define debug(_) cout<<endl<<"d::"<<_<<endl<<endl
#define type(_) typeid(_).name()
inline LL read() {
    
    
	LL x = 0, f = 1;char c = getchar();
	while (!isdigit(c)) {
    
     if (c == '-')f = -f;c = getchar(); }
	while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48ll), c = getchar();
	return x * f;
}

int flag , map[50][50] , jsum , cnt;

int main() {
    
    
//	freopen("data.txt","r",stdin);
	map[1][1] = 1;
	flag = 1;
	jsum = 3;
	cnt = 1;
	while(1) {
    
    
		if(jsum==45)
			break;
		if(flag==1) {
    
    
			Fo(i,1,jsum-1) {
    
    
				map[i][jsum-i] = ++cnt;
			}
			jsum ++;
			flag = 2;
			continue;
		}
		if(flag==2) {
    
    
			Ro(i,jsum-1,1) {
    
    
				map[i][jsum-i] = ++cnt;
			}
			jsum++;
			flag = 1;
			continue;
		}
	}
	cout<<map[20][20];
	return 0;
}


7段码

dfs搜索出所有的7位二进制数,把每个灯管假想为1个点,然后连边

再用并查集去验证是否正确

再说一下为什么有的人算的81,因为全是0的时候也是满足条件的

所以:考场上做完了要输出正确的状态(最好)一一验证

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
typedef long long LL;
#define PI acos(-1)
#define INF 2147483647
#define eps 1e-7
#define L 100005
#define Fo(i,a,b) for(LL i=(a); i<=(b); i++)
#define Ro(i,b,a) for(LL i=(b); i>=(a); i--)
#define Ms(a,b) memset((a),(b),sizeof(a))
#define _ceil(_,__) (_+(__-1))/__
#define debug(_) cout<<endl<<"d::"<<_<<endl<<endl
#define type(_) typeid(_).name()
inline LL read() {
    
    
	LL x = 0, f = 1;char c = getchar();
	while (!isdigit(c)) {
    
     if (c == '-')f = -f;c = getchar(); }
	while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48ll), c = getchar();
	return x * f;
}

#define NUM 10

int used[NUM] , map[NUM][NUM] , fa[NUM] , ans , sum;

void init() {
    
    
	map[1][2] = map[1][6] = 1;
	map[2][1] = map[2][7] = map[2][3] = 1;
	map[3][2] = map[3][7] = map[3][4] = 1;
	map[4][3] = map[4][5] = 1;
	map[5][6] = map[5][7] = map[5][4] = 1;
	map[6][5] = map[6][1] = map[6][7] = 1;
	map[7][5] = map[7][2] = map[7][3] = map[7][6] = 1;
}

int find(int x) {
    
    
	if(fa[x]!=x)
		fa[x] = find(fa[x]);
	return fa[x];
}

void dfs(int num) {
    
    
	if(num>7) {
    
    
		sum = 0;
		Fo(i,1,7) fa[i] = i , sum+=used[i];
		if(sum==0) return ;
		Fo(i,1,7)
			Fo(j,1,7) {
    
    
				if(map[i][j]&&used[i]&&used[j]) {
    
    
					int fu , fv;
					fu = find(i);
					fv = find(j);
					if(fu!=fv)
						fa[fu] = fv;
				}
			}
		Fo(i,1,7)
			Fo(j,1,7)
				if(used[i]&&used[j]&&find(i)!=find(j))
					return ;
		ans++;
		return ;
	}
	used[num] = 1;
	dfs(num+1);
	used[num] = 0;
	dfs(num+1);
}

int main() {
    
    
	//freopen("data.txt","r",stdin);
	init();
	dfs(1);
	cout<<ans;
	return 0;
}


平面分割

这个题的确挺好的,我从别处找到了题解,看这位大佬的解答吧

https://www.zhihu.com/question/426034179

欧拉公式 - 百度百科

成绩统计

签到题 不解释了

回文日期

没办法测试数据,所以网上有只枚举年份和枚举所有日期的几种做法

反正就是枚举吧

子串分值

这个题就比较有意思了,我们就叫它思维题吧

如果我在考场应该就是暴力骗分了吧,就不说了

正解呢就是求每一个位置上的数对答案的贡献

在这里插入图片描述
如图是ababc中每一位对答案的贡献

其实我们用乘法原理想一下可以得到这个公式:

贡献 = 这个字符的位置和前一次出现该字符的位置差 × ( 这个位置之后的所以字符数+1)

然后累加起来就好了

荒岛探测

没有想到太好的解决方案,最多想到了写出椭圆表达式再积分(太麻烦了叭。。。

字串排序

待更

Sum

题目难度不是太高,细心加心态稳的话应该能拿到不少分吧(但愿。。。

还有几个是真的麻烦,就。。。先鸽了叭嘿嘿

猜你喜欢

转载自blog.csdn.net/cls1277/article/details/114988656