2020第十一届蓝桥杯——C/C++程序设计B组(省赛)

今天蓝桥杯打的不尽人意......;

因为还没有拿到题面,就按照回忆写一下关键题的题解吧;

填空:

C:跑步训练:

答案:8879

#include <bits/stdc++.h>
using namespace std;
#define sf(a) scanf("%d",&a)
#define sff(a,b) scanf("%d %d",&a,&b)
#define sfff(a,b,c) scanf("%d %d %d",&a,&b,&c)
#define pf(a) printf("%d\n",a)
#define pff(a,b) printf("%d %d\n",a,b)
typedef long long ll;
const int N=1e4+7,INF=0x3f3f3f3f; 

int p[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int ru[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
int main()
{
		int year=2000,m=1,d=1;
		int res=6;
		int ans=0;
		while(1)
		{
			if(res>7) res=1;
			if((year%4==0&&year%100!=0)||year%400==0)
			{
				if(d>ru[m])
				{
					m++;d=1;
					if(m>12) year++,m=1;
				}
			}
			else
			{
				if(d>p[m])
				{
					m++;d=1;
					if(m>12) year++,m=1;
				}
			}
			if(res==1||d==1) ans+=2;
			else ans+=1;
			if(year==2020&&m==10&&d==1) break;
			d++;res++;
		}
		cout <<ans<<endl;
		return 0;
}

D:数码管 

思路:依次给数码管的每个段标号,顺时针1,2,3,4,5,6,中间为7,然后用map标记下都哪些段是相连的;然后二进制枚举所有的状态,对于每一个状态都重新建图,然后跑图看是否联通即可

答案:80

#include <bits/stdc++.h>
using namespace std;
#define sf(a) scanf("%d",&a)
#define sff(a,b) scanf("%d %d",&a,&b)
#define sfff(a,b,c) scanf("%d %d %d",&a,&b,&c)
#define pf(a) printf("%d\n",a)
#define pff(a,b) printf("%d %d\n",a,b)
typedef long long ll;
const int N=1e4+7,INF=0x3f3f3f3f; 
int e[N],ne[N],h[N],idx;
map<pair<int,int>,int > mapp;
void addd(int a,int b)
{
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void add(int a,int b)
{
	mapp[{a,b}]=mapp[{b,a}]=1;
}
bool st[N];
int a[N];
map<int,int> mp;
void dfs(int u,int fa)
{
	mp[u]++;
	st[u]=1;
	for(int i=h[u];i!=-1;i=ne[i])
	{
		int j=e[i];
		if(j==fa||st[j]) continue;
		dfs(j,u);
	}
}
int main()
{
	add(1,6);add(6,1);
	add(1,2);add(2,1);
	add(5,6);add(6,5);
	add(2,3);add(3,2);
	add(3,4);add(4,3);
	add(4,5);add(5,4);
	add(6,7);add(7,6);
	add(2,7);add(7,2);
	add(5,7);add(7,5);
	add(3,7);add(7,3);
	int ans=0;
	
	for(int i=0;i<(1<<7);i++)
	{
		memset(st,0,sizeof st);
		memset(e,0,sizeof e);
		memset(ne,0,sizeof ne);idx=0;
		memset(h,-1,sizeof h);
		int cnt=0;
		mp.clear();
		for(int j=0;j<7;j++)
		{
			if((i>>j)&1)
			{
				a[cnt++]=j+1;
			}
		}
		for(int x=0;x<cnt;x++)
		{
			for(int y=0;y<cnt;y++)
			{
				if(mapp[{a[x],a[y]}]) addd(a[x],a[y]);
			}
		}
		if(cnt>0)
		{
			dfs(a[0],-1);
			int flag=1;
			for(int i=0;i<cnt;i++)
			{
				if(mp[a[i]]==0)
				{
					flag=0;
					break;
				}
			}
			if(flag) ans++;
//			if(flag)
//			{
//				for(int i=0;i<cnt;i++) cout <<a[i]<<" ";
//				cout <<endl;
//			}
		}
	}
	cout <<ans<<endl;
}

编程题:

H:子段的值(具体题目忘了)

找每个字母对区间的贡献值即可;

#include <bits/stdc++.h>
using namespace std;
#define sf(a) scanf("%d",&a)
#define sff(a,b) scanf("%d %d",&a,&b)
#define sfff(a,b,c) scanf("%d %d %d",&a,&b,&c)
#define pf(a) printf("%d\n",a)
#define pff(a,b) printf("%d %d\n",a,b)
typedef long long ll;
const int N=1e6+7;
vector<int> v[100];
char s[N];
int main()
{
	scanf("%s",s+1);
	int len=strlen(s+1);
	for(int i=1;i<=len;i++)
	{
		v[s[i]-'a'].push_back(i);
	}
	ll ans=0;
	ll res=0;
	for(int i=0;i<26;i++)
	{
		int p=i;
		
		if(v[p].size()==0) continue;
		res++;
		ll l=0;
		for(int j=0;j<v[p].size();j++)
		{
			ll pos=v[p][j];
			ll leng;
			if(l==0) leng=pos-1;
			else leng=pos-l-1;
			ans=ans+(leng)*(leng+1)/2;
			l=pos;
		}
		ans+=(len-l)*(len-l+1)/2;
		
	}
	printf("%lld\n",len*(len+1)/2*res-ans);
	return 0;
}

J:平面划分

这道题是有公式的,区域块数量=n+1 + 1*(两条线交点的个数)+ 2*(三条线交点的个数) + ... +(n-1)*(n条线交点的个数)

但不知道会不会爆精度   qaq.....

#include <bits/stdc++.h>
using namespace std;
#define sf(a) scanf("%d",&a)
#define sff(a,b) scanf("%d %d",&a,&b)
#define sfff(a,b,c) scanf("%d %d %d",&a,&b,&c)
#define pf(a) printf("%d\n",a)
#define pff(a,b) printf("%d %d\n",a,b)
typedef long long ll;
const int N=1e6+7;
double a[N],b[N];
map<pair<double,double>,int> mp;
int cnt[N];
int main()
{
	int n;sf(n);
	for(int i=0;i<n;i++)
	{
		scanf("%lf %lf",&a[i],&b[i]);
	}
	for(int i=0;i<n;i++)
	{
		for(int j=i+1;j<n;j++)
		{
			if(a[i]==a[j]) continue;
			double x=(b[j]-b[i])/(a[i]-a[j]),y=a[i]*x+b[i];
			mp[make_pair(x,y)]++;
		}
	}
	map<pair<double,double>,int>::iterator iter;
	ll ans=n+1;
	ll maxx=0;
	for(iter=mp.begin();iter!=mp.end();iter++)
	{
		ll res=iter->second;
		cnt[res]++;
		maxx=max(maxx,res);
	}
	for(int i=1;i<=maxx;i++)
	{
		if(i==1) ans+=i*cnt[i];
		else ans+=(i-1)*cnt[i];
	}
	cout <<ans<<endl;
	return 0;
}
//3
//1 6
//1 2
//-1 3

 

©️2020 CSDN 皮肤主题: 像素格子 设计师:CSDN官方博客 返回首页