【洛谷】P8713 [蓝桥杯 2020 省 A2] 填空问题 的题解

【洛谷】P8713 [蓝桥杯 2020 省 A2] 填空问题 的题解

传送门

A:门牌制作

思路

这题没什么好说的,就直接暴力枚举就行。

代码
#include <bits/stdc++.h>
#define endl "\n"
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
namespace fastIO {
	inline int read() {
		register int x = 0, f = 1;
		register char c = getchar();
		while (c < '0' || c > '9') {
			if(c == '-') f = -1;
			c = getchar();
		}
		while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
		return x * f;
	}
	inline void write(int x) {
		if(x < 0) putchar('-'), x = -x;
		if(x > 9) write(x / 10);
		putchar(x % 10 + '0');
		return;
	}
}
using namespace fastIO;

int main() {
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	int cnt = 0;
	for(int i = 1; i <= 2020; i ++) {
		int temp = i;
		while(temp) {
			if(temp % 10 == 2) cnt ++;
			temp /= 10;
		}
	}
	write(cnt);
	return 0;
}

算出来答案为: 624 624 624

B:既约分数

思路

暴力枚举枚举出分子和分母,然后判断是不是既约分数即可。

代码
#include <bits/stdc++.h>
#define endl "\n"
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
namespace fastIO {
	inline int read() {
		register int x = 0, f = 1;
		register char c = getchar();
		while (c < '0' || c > '9') {
			if(c == '-') f = -1;
			c = getchar();
		}
		while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
		return x * f;
	}
	inline void write(int x) {
		if(x < 0) putchar('-'), x = -x;
		if(x > 9) write(x / 10);
		putchar(x % 10 + '0');
		return;
	}
}
using namespace fastIO;

int main() {
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	int cnt = 0;
	for(int i = 1; i <= 2020; i ++) {
		for(int j = 1; j <= 2020; j ++) {
			if(__gcd(i, j) == 1)  {
				cnt ++;
			}
		}
	}
	write(cnt);
	return 0;
}

算出来答案为: 2481215 2481215 2481215

C:蛇形填数

思路

从右上角到左下角,再从左下角到右上角, c n t cnt cnt 记录要填的数,数组里存的数字表示该位置应该填的数, u u u 代表横坐标, d d d 代表纵坐标。

横坐标降为 1 1 1 时,填完数后纵坐标 + 1 +1 +1

纵坐标降为 1 1 1 时,填完数后横坐标 + 1 +1 +1

提醒一点:求的是第 20 20 20 行第 20 20 20 列,这可不是 20 × 20 20 \times 20 20×20 的格子数就可以模拟完的,数组得开大点。

代码
#include <bits/stdc++.h>
#define endl "\n"
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
namespace fastIO {
	inline int read() {
		register int x = 0, f = 1;
		register char c = getchar();
		while (c < '0' || c > '9') {
			if(c == '-') f = -1;
			c = getchar();
		}
		while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
		return x * f;
	}
	inline void write(int x) {
		if(x < 0) putchar('-'), x = -x;
		if(x > 9) write(x / 10);
		putchar(x % 10 + '0');
		return;
	}
}
using namespace fastIO;

int main() {
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	int cnt = 0, x = 1, y = 1, a[105][105];
	memset(a, 0, sizeof(a));
	a[x][y] = ++ cnt;
	while(!a[20][20]) {
		x ++;
		while(x != 1) {
			a[x --][y ++] = ++ cnt;
		}
		a[x][y] = ++ cnt;
		y ++;
		while(y != 1) {
			a[x ++][y --] = ++ cnt;
		}
		a[x][y] = ++ cnt;
	}
	write(a[20][20]);
	return 0;
}

算出来答案为: 761 761 761

D:七段码

思路
  1. 因为 a b c d e f g abcdefg abcdefg 每条管(或者叫边)只有发光和不发光两种状态,所以可以状压,去用一个 7 7 7 位的 01 01 01 串表示该七段码管的状态。

  2. 枚举七段码管所有可能出现的状态。

  3. DFS 去判断每个状态里发光的边是否连通即可。

代码
#include <bits/stdc++.h>
#define endl "\n"
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
namespace fastIO {
	inline int read() {
		register int x = 0, f = 1;
		register char c = getchar();
		while (c < '0' || c > '9') {
			if(c == '-') f = -1;
			c = getchar();
		}
		while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
		return x * f;
	}
	inline void write(int x) {
		if(x < 0) putchar('-'), x = -x;
		if(x > 9) write(x / 10);
		putchar(x % 10 + '0');
		return;
	}
}
using namespace fastIO;
bool g[8][8], vis[8], vis1[8];
int res = 0, ans, cnt;
string s;
string Binary(int x) {
	string s = "";
	while(x) {
		if(x % 2 == 0) s = '0' + s;
		else s = '1' + s;
		x /= 2;
	}
	return s;
}
void dfs(int x) {
	if(cnt == ans) {
		res++;
		return;
	}
	for(int i = 1; i <= 7; i ++) {
		if(vis1[i] || !g[x][i] || !vis[i]) continue;
		cnt++;
		vis1[i] = true;
		dfs(i);
	}
}
void check(int i) {
	for(int i = 1; i <= 7; i++) vis[i] = vis1[i] = false;
	s = Binary(i);
	ans = 0;
	for(int i = s.length() - 1; i >= 0; i--)
		if(s[i] == '1') vis[s.length()-i] = true,ans++;
	for(int i = 1; i <= 7; i++)
		if(vis[i]) {
			vis1[i] = true;
			cnt = 1;
			dfs(i);	
        return;
		}
}
int main() {
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	memset(g, false, sizeof(g));
	g[1][2] = g[1][6] = 1;
	g[2][1] = g[2][7] = g[2][3] = 1;
	g[3][2] = g[3][4] = g[3][7] = 1;
	g[4][5] = g[4][3] = 1;
	g[5][6] = g[5][7] = g[5][4] = 1;
	g[6][1] = g[6][7] = g[6][5] = 1;
	g[7][2] = g[7][3] = g[7][5] = g[7][6] = 1;
	for(int i = 1; i < (1<<7); i++)
		check(i);
	write(res);
	return 0;
}

算出来答案为: 80 80 80

E:平面分割

思路

看到这个题,首先会发现是无法用程序去模拟分割的,所以肯定有一定的规律。

规律都是由小到大得出来的,所以我们先从一条直线看起:

如果只有直线,要想构造的分割块最多,那么新添加的直线就要与之前所有的直线相交,而且不能经过之前的直线所形成的交点。

所以规律:

平面上有 0 0 0 条直线,有 1 1 1 个部分。

平面上有 1 1 1 条直线,可以划分出 1 + 1 1+1 1+1 个部分。

平面上有 2 2 2 条直线,可以划分出 1 + 1 + 2 1+1+2 1+1+2 个部分。

平面上有 3 3 3 条直线,可以划分出 1 + 1 + 2 + 3 1+1+2+3 1+1+2+3 个部分。

然后就不难想到平面上有 n n n 条直线时,其可划分出的部分最多为 z ( n ) = n × ( n + 1 ) ÷ 2 + 1 z(n) = n \times (n + 1) \div 2 + 1 z(n)=n×(n+1)÷2+1

那如果加上圆呢?

首先必须记住一点,这个圆的大小是任意的,这也是直线和圆能分开考虑的关键。

打个表找一下规律:

可以看到 f ( n , m ) = f ( n , m − 1 ) + 2 × ( n + m − 1 ) f(n , m) = f(n, m - 1) + 2 \times (n + m - 1) f(n,m)=f(n,m1)+2×(n+m1),其中 f ( n , m ) f(n, m) f(n,m) 表示 n n n 条直线, m m m 个圆时的分割块个数。

代码
#include <bits/stdc++.h>
#define endl "\n"
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
namespace fastIO {
	inline int read() {
		register int x = 0, f = 1;
		register char c = getchar();
		while (c < '0' || c > '9') {
			if(c == '-') f = -1;
			c = getchar();
		}
		while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
		return x * f;
	}
	inline void write(int x) {
		if(x < 0) putchar('-'), x = -x;
		if(x > 9) write(x / 10);
		putchar(x % 10 + '0');
		return;
	}
}
using namespace fastIO;

int main() {
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
    int num = 20 * 21 / 2 + 1;
    for(int i = 1; i <= 20; i ++) {
        num += 2 * (i + 20 - 1);
    }
    write(num);
	return 0;
}

算出来答案为: 1391 1391 1391

AC代码

#include<iostream>
using namespace std;
int main() {
    string ans [] = {
        "624", 
        "2481215", 
        "761", 
        "80", 
        "1391", 
    };
    char T;
    cin >> T;
    cout << ans[T - 'A'] << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值