第十一届蓝桥杯第二场

今年因为疫情原因,第十一届蓝桥杯举办了三场省赛,参加的第二场,水了个省一,第一次参加没啥经验。填空因为粗心对了两个,大题都是瞎搞,最后两题骗分。没想到最后省一。坐等国赛。

把错题再写下。

试题 C: 蛇形填数

如下图所示,小明用从 1 开始的正整数“蛇形”填充无限大的矩阵。
1 2 6 7 15 :::
3 5 8 14 :::
4 9 13 :::
10 12 :::
11 :::
:::
容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20 列
的数是多少 ?

#include<bits/stdc++.h>

using namespace std;
const int N=1e3+5;
int a[N][N];
int main()
{
	int n=1,cnt=1;
	while(1){
		int t=n;
		if(t&1){
			while(t){
				a[t][n-t+1]=cnt++;
				t--;
			}
		}else{
			while(t){
				a[n-t+1][t]=cnt++;
				t--;
			}
		}
		n++;
		if(n==50)break;
	} 
	for(int  i=1;i<=10;i++){
		for(int j=1;j<=10;j++)
		printf("%3d",a[i][j]);
		printf("\n");
	}
	cout<<a[20][20]<<'\n';
  return 0;
}


试题 D: 跑步锻炼

【问题描述】
小蓝每天都锻炼身体。
正常情况下,小蓝每天跑 1 千米。如果某天是周一或者月初(1 日),为了
激励自己,小蓝要跑 2 千米。如果同时是周一或月初,小蓝也是跑 2 千米。
小蓝跑步已经坚持了很长时间,从 2000 年 1 月 1 日周六(含)到 2020 年
10 月 1 日周四(含)。请问这段时间小蓝总共跑步多少千米?
思路:按照天数模拟,还有星期。考试的时候条件写错了,算成了8878亏死。10分就这样没了

#include<bits/stdc++.h>

using namespace std;
const int N=1e3+5;
int dir[12]={31,28,31,30,31,30,31,31,30,31,30,31};
bool run_year(int y)
{
	if(y%400==0||y%4==0&&y%100!=0)return true;
	else return false;
}
int main()
{
	int week=5,flag=0,res=0;
	for(int i=2000;i<=2020;i++){
		if(flag)break;
		for(int j=0;j<12;j++){
			if(flag)break;
			int days=dir[j];
			if(run_year(i)&&j==1){
				days++;
//				cout<<i<<'\n';
			}
			for(int k=1;k<=days;k++){
				res++;
				week=(week+1)%7;
				if(k==1||week==1)res++;
				if(i==2020&&j==9&&k==1){
//					cout<<week<<'\n';
					flag=1;break;
				}
				
			}
		}
	}
//	cout<<week<<'\n';
	cout<<res<<'\n';
  return 0;
}


试题 E: 七段码


思路:就是一个子集问题,每个管子选和不选,选完之后用并查集判断是否是一个连通块。

#include<bits/stdc++.h>

using namespace std;
const int N=10;
int e[N][N],vis[N],pre[N],res,ans[8];
int find(int x)
{
	return x==pre[x]?x:pre[x]=find(pre[x]);
}
void init()
{
	for(int i=1;i<=7;i++)pre[i]=i;	
}
void print_()
{
//	cout<<"-------------"<<'\n';
//	for(int i=1;i<=7;i++){
//		if(vis[i])cout<<i<<' ';
//	}
//	cout<<'\n'<<"------------"<<'\n';
	int cnt=0;
	for(int i=1;i<=7;i++){
		if(vis[i])cnt++;
	}
	ans[cnt]++;
}
void dfs(int cur)
{
	if(cur==8){
//		res++;
		int cnt=0;
		for(int i=1;i<=7;i++)
		if(vis[i])cnt++;
		if(cnt==1){
			res++;
			print_();
			return ;
		}
		init();
		for(int i=1;i<=7;i++){
			for(int j=1;j<=7;j++){
				if(e[i][j]&&vis[i]&&vis[j]){
					int fx=find(i),fy=find(j);
					if(fx!=fy)pre[fx]=fy;
				}
			}
		}
		int cnt1=0;
		for(int i=1;i<=7;i++)
		if(pre[i]==i&&vis[i])cnt1++;
		if(cnt1==1){
			res++;
			print_();
		}
		return ;
	}
	vis[cur]=1;
	dfs(cur+1);
	vis[cur]=0;
	dfs(cur+1);
}
int main()
{
	e[1][2]=e[2][1]=1;
	e[2][3]=e[3][2]=1;
	e[3][4]=e[4][3]=1;
	e[4][5]=e[5][4]=1;
	e[2][7]=e[7][2]=1;
	e[3][7]=e[7][3]=1;
	
	e[5][7]=e[7][5]=1;
	e[5][6]=e[6][5]=1;
	e[1][6]=e[6][1]=1;
	e[6][7]=e[7][6]=1;
	dfs(1);
	cout<<res<<'\n';
//	for(auto x:ans)
//	cout<<x<<'\n';
  return 0;
}


试题 G: 回文日期


思路:模拟,细节感觉还挺多的,考试的时候一开始方向错了,后来直接取前四位,然后枚举判断符合条件的。

#include<bits/stdc++.h>

using namespace std;
const int N=1e3+5;
int dir[12]={31,28,31,30,31,30,31,31,30,31,30,31};
/*
 1 	2	3	4	 5	 6	 7	 8	 9	 10	 11	 12
 31	28	31  30	 31  30  31  31  30	 31	 30  31
*/
bool run_year(int y)
{
	if(y%400==0||y%4==0&&y%100!=0)return true;
	return false;
}
bool check1(int y,int m,int d)
{
	if(m<1||m>12)return true;
	int days=dir[m-1];
	if(d<1)return true; 
	if(m==2&&run_year(y))days++;
	if(d>days)return true;
	return false;
}
bool check2(int y,int m,int d)
{
	int a,b;
	a=y/100;b=y%100;
	int x1=a/10,x2=a%10;
	int x3=b/10,x4=b%10;
	int x5=m/10,x6=m%10;
	int x7=d/10,x8=d%10;
	if(x1!=x3)return false;
	if(x3!=x6)return false;
	if(x6!=x8)return false;
	
	if(x2!=x4)return false;
	if(x4!=x5)return false;
	if(x5!=x7)return false;
	return true;
	
}
int main()
{
	int N;
	cin>>N;
	int y=N/10000;
	N=N%10000;
	int m=N/100;
	int d=N%100;
	int flag1=false,flag2=false;
//	cout<<y<<' '<<m<<' '<<d<<'\n';
	for(int i=y;i<=9999;i++){
//		int i=1234;
		int t=i,cnt=0,mm=0,dd=0;
		while(t){
			int temp=t%10;
			mm=mm*10+temp;
			cnt++;
			t/=10;
			if(cnt==2)break;
		}
		while(t){
			int temp=t%10;
			dd=dd*10+temp;
			t/=10;
		}
//		cout<<mm<<' '<<dd<<'\n';
		if(check1(i,mm,dd))continue;//不符合月份和日 
		if(i==y&&mm==m&&dd==d)continue;//除去输入的符合的情况
		
//		if(i==2021){
//			cout<<mm<<' '<<dd<<'\n';
//		}
		 if(!flag1){
		 	printf("%d%02d%02d\n",i,mm,dd);
		 	flag1=1;
		 }
		 if(!flag2&&check2(i,mm,dd)){
		 	printf("%d%02d%02d\n",i,mm,dd);
		 	flag2=1;
		 }
		 if(flag1&&flag2)break;
	}
//	int x=1234;
//	int a=x/100,b=x%100;
//	cout<<a<<' '<<b<<'\n';
	
  return 0;
}
/*
1:
20200202

20211202 
21211212

2.
20211202

20300302
21211212
3.
21211212

21300312
30300303
4.
20300302

20400402
21211212
5.
21211212

21300312
30300303
6.
30300303

30400403
40400404
7.
30400403

30500503
40400404
8.
30500503

30600603
40400404
*/


试题 H: 子串分值和

【问题描述】
对于一个字符串 S,我们定义 S 的分值 f(S) 为 S 中出现的不同的字符个 数。例如 f(”aba”) = 2,f(”abc”) = 3, f(”aaa”) = 1。 现在给定一个字符串 S[0…n−1](长度为 n),请你计算对于所有 S 的非空 子串 S[i…j](0≤i≤ j < n),f(S[i…j]) 的和是多少。
【输入格式】
输入一行包含一个由小写字母组成的字符串 S。
【输出格式】
输出一个整数表示答案。
【样例输入】 ababc
【样例输出】 28
【评测用例规模与约定】 对于 20% 的评测用例,1≤n≤10; 对于 40% 的评测用例,1≤n≤100;
对于 50% 的评测用例,1≤n≤1000;
对于 60% 的评测用例,1≤n≤10000;
对于所有评测用例,1≤n≤100000。
思路:考场上一开始写的O(n^3),后来找规律降低到了O(n ^2)。正解应该是O(n)的。害

#include<bits/stdc++.h>

using namespace std;
const int N=1e3+5;
int main()
{
   freopen("in1.txt","r",stdin);
   freopen("out1.txt","w",stdout);
   string s;
   cin>>s;
   int n=s.size(),res=0;
   for(int i=0;i<n;i++){
   	map<char,int >mp;
   	for(int j=i;j<n;j++){
   		if(!mp[s[j]]){
   			res+=n-j;
   			mp[s[j]]=1;
   		}
   	}
   }
   cout<<res<<'\n';
 return 0;
}

A组的该题换了一种说法

试题 H: 子串分值

【问题描述】 对于一个字符串 S,我们定义 S 的分值 f(S ) 为 S 中恰好出现一次的字符 个数。例如 f(”aba”) = 1,f(”abc”) = 3, f(”aaa”) = 0。 现在给定一个字符串 S [0…n − 1](长度为 n),请你计算对于所有 S 的非空 子串 S [i… j](0 ≤ i ≤ j < n),f(S [i… j]) 的和是多少。

【输入格式】 输入一行包含一个由小写字母组成的字符串 S。

【输出格式】 输出一个整数表示答案。

【样例输入】 ababc

【样例输出】 21

思路:枚举每个子串,然后统计即可。

#include <bits/stdc++.h>
#define pb push_back//vector,deque
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N=2e5+5;
int vis[26];
void solve()
{
    int t;
    cin>>t;
    while(t--){
    }
}
ll fun()
{
	ll sum=0;
	for(int i=0;i<26;i++){
		if(vis[i]==1)sum++;
	}
	return sum;
}
int main() {
	//solve();
	string s;
	cin>>s;
	int n=s.size();
	ll res=0;
	for(int i=0;i<n;i++){
		for(int j=i;j<n;j++){
			string t;
			memset(vis,0,sizeof vis);
			for(int k=i;k<=j;k++){
				vis[s[k]-'a']++;
				t+=s[k];
			}
			res+=fun();
			//cout<<t<<'\n';
		}
	}
	cout<<res<<'\n';
    return 0;
}
/*
ababc
*/

最后两题都是直接骗分了。坐等国赛被大佬虐。

猜你喜欢

转载自blog.csdn.net/qq_43566782/article/details/109384850