洛谷 P8721 [蓝桥杯 2020 省 AB3] 填空问题(缺少 inc.txt, E 题数据) 题解

题目分析

A 数青蛙

根据青蛙的个数分类计算:

  • 青蛙数小于等于 2 2 2:此时青蛙数、眼睛数、嘴巴数和腿数读出来只读 1 1 1 个字,故此时一句话 14 14 14 个字。
  • 青蛙数大于 2 2 2,小于等于 5 5 5:此时青蛙数、眼睛数和嘴巴数读出来只读 1 1 1 个字,腿数读出来只读 2 2 2 个字,故此时一句话 15 15 15 个字。
  • 青蛙数大于 5 5 5,小于等于 9 9 9:此时青蛙数和嘴巴数读出来只读 1 1 1 个字,眼睛数读出来只读 2 2 2 个字,腿数读出来只读 3 3 3 个字,故此时一句话 17 17 17 个字。
  • 青蛙数等于 10 10 10:此时青蛙数和嘴巴数读出来只读 1 1 1 个字,眼睛数和腿数读出来只读 2 2 2 个字,故此时一句话 16 16 16 个字。
  • 青蛙数大于 10 10 10,小于等于 14 14 14:此时青蛙数和嘴巴数读出来只读 2 2 2 个字,眼睛数和腿数读出来只读 3 3 3 个字,故此时一句话 20 20 20 个字。
  • 青蛙数等于 15 15 15:此时青蛙数、嘴巴数、眼睛数和腿数读出来只读 2 2 2 个字,故此时一句话 18 18 18 个字。
  • 青蛙数大于 15 15 15,小于等于 19 19 19:此时青蛙数和嘴巴数读出来只读 2 2 2 个字,眼睛数和腿数读出来只读 3 3 3 个字,故此时一句话 20 20 20 个字。
  • 青蛙数等于 20 20 20:此时青蛙数、嘴巴数、眼睛数和腿数读出来只读 2 2 2 个字,故此时一句话 18 18 18 个字。

综上所述,可以得到共有 2 × 14 + 3 × 15 + 4 × 17 + 16 + 4 × 20 + 18 + 4 × 20 + 18 = 28 + 45 + 68 + 16 + 80 + 18 + 80 + 18 = 353 2\times14+3\times15+4\times17+16+4\times20+18+4\times20+18=28+45+68+16+80+18+80+18=353 2×14+3×15+4×17+16+4×20+18+4×20+18=28+45+68+16+80+18+80+18=353 个字。

B 互质

解法一

对于任意两个数 x x x y y y,如果它们互质,那么 gcd ⁡ ( x , y ) \gcd(x,y) gcd(x,y) 的值就会等于 1 1 1。所以可以用 1 1 1 2020 2020 2020 中的数都与 1018 1018 1018 计算一次最大公因数,如果结果为 1 1 1,就累加个数。

代码如下:

#include<iostream>
#include<algorithm>
using namespace std;
signed main() {
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	int ans=0;
	for(int i=1;i<=2020;++i) if(__gcd(i,1018)==1) ++ans;//如果最大公因数为1就累加和
	cout<<ans;
	return 0;
}

最终得到答案为 1008 1008 1008

解法二

2018 2018 2018 分解质因数得到 2 × 509 = 1018 2\times509=1018 2×509=1018

1 1 1 2020 2020 2020 中,有 2020 ÷ 2 = 1010 2020\div2=1010 2020÷2=1010 个数是 2 2 2 的倍数。

1 1 1 2020 2020 2020 中,有 ⌊ 2020 ÷ 509 ⌋ = 3 \lfloor 2020\div509\rfloor=3 2020÷509=3 个数是 509 509 509 的倍数。

1 1 1 2020 2020 2020 2 2 2 509 509 509 共有的倍数有 ⌊ 2020 ÷ lcm ( 2 , 509 ) ⌋ = ⌊ 2020 ÷ 1018 ⌋ = 1 \lfloor2020\div \text{lcm}(2,509)\rfloor=\lfloor2020\div1018\rfloor=1 2020÷lcm(2,509)⌋=2020÷1018=1 个。

故得出在 1 1 1 2020 2020 2020 中与 2018 2018 2018 互质的数有 2020 − 1010 − 3 + 1 = 1008 2020-1010-3+1=1008 202010103+1=1008 个。

C 车牌

用 dfs 进行搜索即可。

代码如下:

#include<iostream>
using namespace std;
int ans=0;
void dfs(string str) {//dfs搜索
	if(str.size()==6) {//有6位了累加答案
		++ans;
		return;
	}
	if(str.size()<3) {//当前长度小于3
		for(string i="0";i[0]<='9';++i[0]) if(str.size()<2||!(str[str.size()-1]==i[0]&&str[str.size()-2]==str[str.size()-1])) dfs(str+i);
		for(string i="A";i[0]<='F';++i[0]) if(str.size()<2||!(str[str.size()-1]==i[0]&&str[str.size()-2]==str[str.size()-1])) dfs(str+i);
	}
	//当前长度大于3
	else for(string i="0";i[0]<='9';++i[0]) if(!(str[str.size()-1]==i[0]&&str[str.size()-2]==str[str.size()-1])) dfs(str+i);
}
signed main() {
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	dfs("");
	cout<<ans;
	return 0;
}

D Fibonacci 集合

可以使用优先队列。

对于任意一个队列中的元素 x x x,判断 3 × x + 2 3\times x+2 3×x+2 5 × x + 3 5\times x+3 5×x+3 8 × x + 5 8\times x+5 8×x+5 是否已经出现过,未出现过就将其压入队列中。若 x x x 是队列中第第 2020 2020 2020 个元素时,就输出 x x x

代码如下:

#include<iostream>
#include<queue>
using namespace std;
bool flag[1000000];//统计该值是否出现过
int num;//统计当前元素是第几个
signed main() {
	priority_queue<int,vector<int>,greater<int>>que;//优先队列
	que.push(1),que.push(2),que.push(3),que.push(5),que.push(8),flag[1]=flag[2]=flag[3]=flag[5]=flag[8]=true;
	while(!que.empty()) {
		++num;//累加个数
		if(num==2020) {
			cout<<que.top();//如果是第2020个就输出
			return 0;
		}
		//判断是否出现过,若未出现,将其压入队列
		if(flag[que.top()*3+2]==false) flag[que.top()*3+2]=true,que.push(que.top()*3+2);
		if(flag[que.top()*5+3]==false) flag[que.top()*5+3]=true,que.push(que.top()*5+3);
		if(flag[que.top()*8+5]==false) flag[que.top()*8+5]=true,que.push(que.top()*8+5);
		que.pop();//记得出队
	}
	return 0;
}

最终得到答案为 41269 41269 41269

E 上升子串

因为没有数据,就只附个代码了(思路:深搜):

#include<iostream>
using namespace std;
int ans,n,m,sum[1000][1000];//n为行数,m为列数
string str[1000];
int dfs(int x,int y) {
	if(sum[x][y]) return sum[x][y];//已经搜索过就不用再搜
	sum[x][y]=1;//初始赋值为1
	//搜索
	if(x+1<n&&str[x+1][y]>str[x][y]) sum[x][y]+=dfs(x+1,y);
	if(x&&str[x-1][y]>str[x][y]) sum[x][y]+=dfs(x-1,y);
	if(y+1<n&&str[x][y+1]>str[x][y]) sum[x][y]+=dfs(x,y+1);
	if(y&&str[x][y-1]>str[x][y]) sum[x][y]+=dfs(x,y-1);
	return sum[x][y];//放回答案
}
signed main() {
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i=0;i<n;++i) cin>>str[i];
	for(int i=0;i<n;++i) for(int j=0;j<m;++i) ans+=dfs(i,j);//搜索,累加答案
	cout<<ans;
	return 0;
}

请注意:本题正确答案是 qwq \texttt{qwq} qwq

Code

#include<iostream>
using namespace std;
signed main() {
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	string ans[]={
		"353",
		"1008",
		"4002750",
		"41269",
		"qwq"
	};
	cout<<ans[getchar()-'A'];
	return 0;
}
  • 32
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
洛谷p5736 【深基7.例2】质数筛是一个关于质数筛法的目,要求我们根据输入的一个正整数n,找出小于等于n的所有质数。 质数是指只能被1和自身整除的大于1的整数,比如2、3、5、7等。质数筛法是一种常见且高效的找出质数的方法。 在这道中,我们需要使用质数筛法来找出小于等于n的所有质数。首先,我们定义一个boolean类型的数组isPrime,用来标记每个数字是否是质数。初始时,我们将isPrime数组的所有元素都设置为true。 然后,我们从2开始遍历到n,对于每个数字i,如果isPrime[i]为true,说明这个数字是质数。那么我们就需要将i的倍数都标记为false,因为这些倍数一定不是质数。具体做法是,从2*i开始,每次增加i,将对应的isPrime数组的元素都置为false。 遍历结束后,isPrime数组中为true的元素即为小于等于n的所有质数。我们可以遍历isPrime数组,将为true的下标即为质数输出即可。 这个算法的时间复杂度是O(nloglogn),相较于直接遍历每个数字并判断是否是质数的方法,时间复杂度更低,效率更高。 对于这个目的java实现,我们可以使用一个boolean数组isPrime来标记每个数字是否是质数,使用一个ArrayList来存储所有的质数,最后将ArrayList转化为数组输出。 代码示例如下: ``` import java.util.ArrayList; public class Main{ public static void main(String[] args){ int n = 100; // 输入的正整数n boolean[] isPrime = new boolean[n+1]; // 标记每个数字是否是质数的数组 ArrayList<Integer> primes = new ArrayList<>(); // 存储质数的ArrayList // 初始化isPrime数组 for(int i=2; i<=n; i++){ isPrime[i] = true; } // 质数筛法 for(int i=2; i<=n; i++){ if(isPrime[i]){ primes.add(i); for(int j=2*i; j<=n; j+=i){ isPrime[j] = false; } } } // 将ArrayList转化为数组输出 int[] result = new int[primes.size()]; for(int i=0; i<primes.size(); i++){ result[i] = primes.get(i); } // 输出结果 for(int i=0; i<result.length; i++){ System.out.print(result[i] + " "); } } } ``` 这样,我们就可以通过这段代码来实现洛谷p5736目的要求,找出小于等于输入的正整数n的所有质数,并将它们按从小到大的顺序输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值