2020第11回ブルーブリッジカップC / C ++州大会グループA問題解決策

A

ここに画像の説明を挿入

624
は各数値をトラバースし、残りを取り、各ビットを判断します

#include<iostream>
using namespace std;

int main()
{
    
    
	int cnt=0;
	for(int i=1;i<=2020;i++)
	{
    
    
		int tmp=i;
		while(tmp)
		{
    
    
			if(tmp%10==2)
				cnt++;
			tmp/=10;
		}
	}
	cout<<cnt;
	return 0;
}

B


24812152
最大公約数が1であるかどうかを判断するための2サイクル

#include<iostream>
using namespace std;

int gcd(int a,int b)
{
    
    
	if(b==0)
	return a;
	else 
	return gcd(b,a%b);	
}

int main()
{
    
    
	int cnt=0;
	for(int i=1;i<=2020;i++)
		for(int j=1;j<=2020;j++)
			if(gcd(i,j)==1)
				cnt++;
	cout<<cnt;
	return 0;
}

C

ここに画像の説明を挿入
761
法則を直接見つける方が速い
(1,1)1 = 0 + 1
(2,2)5 =(1 + 2)+2
(3,3)13 =(1 + 2 + 3 + 4)+3
( i、I)x =(1 + 2 + 3 +…+ 2(i-1))+ i =(i-1)(2i-1)+ i
、蛇型の塗りつぶしコード

#include<iostream>
using namespace std;

int a[1001][1001];

int main()
{
    
    
	int cnt=1;
	int i=1,j=1;
	a[i][j]=cnt;
	while(cnt<10000)
	{
    
    
		
		if(i==1)
			j++;
		a[i][j]=++cnt;
		while(j>1)
			a[++i][--j]=++cnt;
		if(j==1)
			i++;
		a[i][j]=++cnt;
		while(i>1)
			a[--i][++j]=++cnt;
	}
	cout<<a[20][20];
	return 0;
}

D

ここに画像の説明を挿入
80の
建物の地図、dfs。各ライトはオンまたはオフにすることができ、2 ^ 7を列挙します。

#include<iostream>
using namespace std;

const int N=8;
int map[N][N],fa[N],vis[N],ans;

int getfa(int i)										//寻找根节点 
{
    
    
	if(fa[i]==i)
		return i;
	return fa[i]=getfa(fa[i]);							//压缩路径 
}

void dfs(int k)
{
    
    
	if(k>7)												//7个灯都枚举完了 
	{
    
    
		for(int i=1;i<=7;i++)							//先把自己设为自己的父节点 
			fa[i]=i;
		for(int i=1;i<=7;i++)
			for(int j=1;j<=7;j++)
			{
    
    
				if(map[i][j]&&vis[i]&&vis[j])			//将连通且亮着的灯,并在一块 
				{
    
    
					int faa=getfa(i),fab=getfa(j);
					if(faa!=fab)
						fa[faa]=fab;
				}
			}
		int cnt=0;
		for(int i=1;i<=7;i++)							//有几个根节点说明有几个集合 
			if(fa[i]==i&&vis[i])						//亮着的灯的集合数 
				cnt++;
		if(cnt==1)										//都连通的话,只有一个集合 
			ans++;							
		return;
	}
	vis[k]=1;											//k灯亮  dfs中k+1亮和灭 
	dfs(k+1);
	vis[k]=0;											//k灯灭 
	dfs(k+1);
}

int main()
{
    
    
	map[1][2]=map[2][1]=1;map[1][6]=map[6][1]=1;	//连通的存图 
	map[6][7]=map[7][6]=1;map[6][5]=map[5][6]=1;
	map[2][7]=map[7][2]=1;map[2][3]=map[3][2]=1;
	map[5][7]=map[7][5]=1;map[5][4]=map[4][5]=1;
	map[3][7]=map[7][3]=1;map[4][3]=map[3][4]=1;
	dfs(1);
	cout<<ans;
	return 0;
}

E

ここに画像の説明を挿入
1391
同じ点で交差しない任意の線(直線と曲線を含む)の間で、平面をできるだけ多くの部分に分割できます。
オイラーの定理V-E + F-T = 1、T = 0、 F = 1 + E-Vについて解く場合、点の数Vと辺の数Vについて解くだけで済みます。
私たちの分析によれば、任意の2本の直線が交点を持つことができます。数は(202)です。任意の2つの円の間に2つの交点があります。数は2・(202)です。任意の円と直線の間に2つの交点があり、数は20×20×2
なので、V =(202)+2です。 ⋅(202)+ 20×20×2 = 1370
同じことが当てはまります私たちの分析では、直線はそれぞれ1点で残りの19本の直線と交差し、20個の円はそれぞれ2点で交差するため、19個あります+ 20×2 =線上の59点、直線は60辺に分割されます。円は残りの19個の円と20本の直線がそれぞれ2点で交差し、合計(19 + 20)×2 = 78ポイント、円は78の辺に分割される
ため、E = 60×20 + 78×20 = 2760
の答えが得られます:F = 1 + 2760-1370 = 1391

F

ここに画像の説明を挿入
ここに画像の説明を挿入

#include<iostream>
#include<cstdio>
using namespace std;

int a[100001];

int main()
{
    
    
	int n,maxx=-1,minn=101;
	cin>>n;
	long long s=0;
	double ave;
	for(int i=1;i<=n;i++)
	{
    
    
		scanf("%d",&a[i]);
		s+=a[i];
		maxx=max(maxx,a[i]);
		minn=min(minn,a[i]);
	}
	ave=s/double(n);
	printf("%d\n%d\n%.2lf",maxx,minn,ave);	
}

G

ここに画像の説明を挿入
ここに画像の説明を挿入
各日付を判断し、日付の余りを取り、配列の各ビットを格納し、対応するものが等しいかどうか
を判断します。日付が合法であるかどうかを判断するように注意してください

#include<iostream>
using namespace std;

int main()
{
    
    
	int n,ans1=0,ans2=0;
	int a[10];
	cin>>n;
	for(int i=n+1;;i++)
	{
    
    
		int j=1;
		int tmp=i;
		while(j<=8)
		{
    
    
			a[j++]=tmp%10;
			tmp/=10;
		}
		bool flag=0;
		int m=a[5]*10+a[6],k=a[7]*10+a[8],y;
		switch(m)
		{
    
    
			case 4:
			case 6:
			case 9:
			case 11:
				if(m>30) flag=1;
				break;
			case 2:
				y=a[1]*1000+a[2]*100+a[3]*10+a[4];
				if((y%4==0&&y%100!=0)||y%400==0) {
    
    if(m>29) flag=1;break;}
				else {
    
    if(m>28) flag=1;break;}
			default:
				if(m>31) flag=1;
				break;	
		}
		if(flag)
			continue;
		if(a[1]==a[3]&&a[1]==a[6]&&a[1]==a[8]&&a[2]==a[4]&&a[2]==a[5]&&a[2]==a[7])
			for(int j=8;j;j--)
			{
    
    
				ans2*=10;
				ans2+=a[j];
			}
		if(a[1]==a[8]&&a[2]==a[7]&&a[3]==a[6]&&a[4]==a[5]&&!ans1)
			for(int j=8;j;j--)
			{
    
    
				ans1*=10;
				ans1+=a[j];
			}
		if(ans1&&ans2)
			break;	
	}
	cout<<ans1<<endl<<ans2;
	return 0;
}

H

ここに画像の説明を挿入
ここに画像の説明を挿入
列挙してトリプルサイクルすることができます。このように、nは100未満である必要があります。明らかに
、各文字によって提供される部分文字列数ではありません。その下付き文字は、前後の同じ文字の下付き文字の絶対値です。同じ文字。乗算してから、各文字を累積することが答えです。たとえば
ここに画像の説明を挿入
、図のこの文字列は、位置4 aの寄与部分文字列の数を数え、
最初の添え字は1、最後の文字は6(4 -1)*(6 -4)= 6
4-1はbca(No。234)に対応し、6-4はab(No。45)に対応することを説明
します。bcaを開始位置、baを終了位置とする部分文字列位置はすべて4番目のaのみ
含み、4番目のaのみ含む部分文字列、つまりbca bcab ca cab a abです。
最初は、前後に同じ文字がない場合があることに注意してください

#include<iostream>
#include<string>
using namespace std;

const int N=1e5+5;
int pre[N],nex[N],a[27];
string s;

int main()
{
    
    
	cin>>s;
	s="0"+s;						//下标从1开始 
	int n=s.length()-1;				//长度 
	for(int i=1;i<=n;i++)			//寻找前一个相同字符下标 
	{
    
    
		int c=s[i]-'a';
		pre[i]=a[c];
		a[c]=i;
	}
	for(int i=0;i<26;i++)			//初始化,可能后边没有相同字符    寻找前一个时,未初始,因为a数组默然为0 
		a[i]=n+1;
	for(int i=n;i;i--)				//寻找后一个相同字符下标 
	{
    
    
		int c=s[i]-'a';
		nex[i]=a[c];
		a[c]=i;
	}
	long long int ans=0;
	for(int i=1;i<=n;i++)
		ans+=(long long)(i-pre[i])*(nex[i]-i);//相乘计算累加
	cout<<ans; 
	return 0;
}

ここに画像の説明を挿入
ここに画像の説明を挿入
楕円と三角形の重なり合う部分の領域を見つけてください、許さないでください

J

ここに画像の説明を挿入
ここに画像の説明を挿入
ええと、ええと、まだいいえ、
誰が私にorzを教えてくれるでしょう

おすすめ

転載: blog.csdn.net/m0_54621932/article/details/114024665