第十一屆藍橋杯省賽CC++組第二場比賽

XQ_Chen發表於2020-10-17

第十一屆藍橋杯省賽C/C++組第二場比賽

有錯誤各位大佬指出來哈。

1.找"2" 答案:624

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

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

2.gcd函式,直接搞 答案:2481215

#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
	int ans=0;
	for(int i=1;i<=2020;i++)
	{
		for(int j=1;j<=2020;j++)
		{
			if(__gcd(i,j)==1)
				ans++;
		}	
	}	
	cout<<ans<<endl;
	return 0;
}

3.蛇形圖 答案:761

手算更快,等差數列搞一搞

4.跑步 答案:8879

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

int mon[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

int main()
{
	int y,m,d;
	cin>>y>>m>>d;
	int ans=0;
	int flag=0;
	int week=6;	//用來記錄當天星期幾
    //i,j,k 列舉年月日
	for(int i=2000;i<=y;i++)
	{
		for(int j=1;j<=12;j++)
		{
			int End=mon[j];
			if(((i%4==0&&i%100!=0)||i%400==0) && j==2)
				End++;
			for(int k=1;k<=End;k++)
			{
				ans++;
				if(week==1||k==1)
					ans++;
				if(++week==8)
					week=1;
				if(i==y&&j==m&&k==d)
				{
					flag=1;break;
				}
			}
			if(flag==1)
				break;
		}
	}
	cout<<ans<<endl;
	return 0;
}

5.燈管

這題手算的,算出來81,不知道對錯……

6.及格率,四捨五入

不記得函式,先放大再縮小

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

int n;
void fun(int &num)
{
	if(num%10>4)
	{
		num/=10;
		num++;
	}else
		num/=10;
}
int main()
{
	cin>>n;
	int x;
	int cnt1=0;
	int cnt2=0;
	for(int i=0;i<n;i++)
	{
		cin>>x;
		if(x>=60)
			cnt1++;
		if(x>=80)
			cnt2++;
	}
	int ans1=(cnt1*1.0/n*1.0)*1000;
	int ans2=(cnt2*1.0/n*1.0)*1000;
	fun(ans1);fun(ans2);
	cout<<ans1<<"%"<<endl;
	cout<<ans2<<"%"<<endl;
	return 0;
}

7.下一個迴文年份

列舉年份,生成對應的月日,判斷合法性

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

int mon[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

char Input[10];

//通過年 得到迴文的月日 同時檢查年是否為abab 
void getMD(int y,int &m,int &d,int &ab)
{
	int temp[4]={0};
	int i=0;
	while(y)
	{
		temp[i++]=y%10;
		y/=10;
	}
	m=temp[0]*10+temp[1];
	d=temp[2]*10+temp[3];
	if(temp[0]==temp[2]&&temp[1]==temp[3])
		ab=1;
	else
		ab=0;
}

//檢查年月日的合法性 
bool check(int y,int m,int d)
{
	if(((y%4==0&&y%100!=0)||y%400==0)&&m==2&&(d<1||d>mon[2]+1))
			return 0;
	if(m<1||m>12)
		return 0;
	if(d<1||d>mon[m])
		return 0;
	return 1;
}

int main()
{	
	scanf("%s",&Input);
	int staY=0;
	int x=1;
	for(int i=3;i>=0;i--)
	{
		staY+=(Input[i]-'0')*x;
		x*=10;
	}
	int y1,m1,d1;
	int y2,m2,d2;
	int m,d,ab;
	int flag=0;
	for(int i=staY+1;i<=9999;i++)
	{
		getMD(i,m,d,ab);
		if(check(i,m,d))
		{
			//找到第一次就不會再找了 
			if(flag==0)
			{
				y1=i; m1=m;	d1=d;
				flag=1;
			}
			if(ab==1)
			{
				y2=i; m2=m; d2=d;
				break;
			}
		}
	}
	printf("%04d%02d%02d\n",y1,m1,d1);
	printf("%04d%02d%02d\n",y2,m2,d2);
	return 0;
}

8.算區間不同字母的個數,求和所由子區間

直接計算每個字母的貢獻值,假設每個區間都是第一個出現的字母貢獻,則每個字母貢獻值是左邊沒出現相同字母乘上右邊到最後的長度

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
string str;
ll last[26];	//記錄26個字母上一次出現的位置 
ll ans=0;
int main()
{	
	for(int i=0;i<26;i++)
		last[i]=-1;
	cin>>str;
	ll len=str.size();
	for(ll i=0;i<len;i++)	
	{
		ans+=(i-last[str[i]-'a'])*(len-i);
		last[str[i]-'a']=i;
	}
	cout<<ans<<endl;
	return 0;
}

9. 平面幾何,這題不會,日後學會了來補

10.構造逆序字串,優先最短,其次字典序最小

這題我找規律水過去了一半的資料,其實也不會寫。就不貼程式碼獻醜了

相關文章