十一届蓝桥杯省赛c++组(上)

1、

 数位分离的应用

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

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

2、

 欧几里得算法的应用

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int gcd(int a ,int b)
{
	return b ? gcd(b ,a % b) : a;
}

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;
	return 0;
}

3、

 读完题后先不要急着暴力破解,我们观察可以发现题目所求的20行20列是这个图的对角线数据,而对角线数据是有规律的:1 ,1 + 4 , 1 + 4 + 8 ,1 + 4 + 8 +12 .。。。

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
	int ans = 1 ,cnt = 4;
	for (int i = 1 ;i < 20 ;i ++)
	{
		ans += cnt;
		cnt += 4;
	}
	
	cout << ans;
	
	return 0;
}

4、

 

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

int m[13] = {0 ,31 ,28 ,31 ,30 ,31 ,30 ,31 ,31 ,30 ,31 ,30 ,31};//每个月对应的天数

int main()
{
	int st = 6 ,sum = 0;
	for (int i = 2000 ;i <= 2020 ;i ++)//遍历年份
	{
		int flag = 0;
		if (i % 400 == 0 || (i % 100 != 0 && i % 4 == 0)) flag = 1;//如果是闰年,二月加一天
		
		for (int j = 1 ;j <= 12 ; j ++)//遍历月份
		{				
			int month = m[j];
			if (j == 2) month += flag;
			
			for (int d = 1 ;d <= month ;d ++)//遍历日
			{
				if (d == 1 || st == 1) sum += 2;
				else
					sum += 1;
				
				st ++;
				if (st > 7) st = 1;
				
				if (i == 2020 && j == 10 && d == 1)
				{
					cout << sum;
					return 0;
				}
			}
		}
	}

	return 0;
}

5、

这个题目我个人感觉有点难,倒不是思路的复杂,而是不容易想到如何对题目进行抽象转化。本题的思路就是并查集加dfs。

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

#define N 100

int f[N][N] ,ans ,p[N];
bool vis[N];

int find(int x)
{
	if (x != p[x]) return p[x]= find(p[x]);
	return p[x];
}

void dfs(int x)
{
	if (x == 8)
	{
		for (int i = 1 ;i <= 7 ;i ++) p[i] = i;//初始化并查集 
		
		for (int i = 1 ;i <= 7 ;i ++)
		{
			for (int j = 1 ;j <= 7 ;j ++)
			{
				if (f[i][j] && vis[i] && vis[j])//如果两点之间可以连接,且需要连接,就连接 
				{
					int a = find(i);
					int b = find(j);
					if (a != b) p[a] = b;
				}
			}
		}
		
		int flag = 0;
		for (int i = 1 ;i <= 7 ;i ++)
		{
			if (p[i] == i && vis[i])  flag ++;//枚举连通块 
		}
		
		if (flag == 1) ans ++;//只有连在一起且只有一个连通块的情况才满足题意 
		return;
	}
	
	vis[x] = false;
	dfs(x + 1);
	
	vis[x] = true;
	dfs(x + 1);
}

int main()
{
	f[1][2] = f[1][6] = 1;
	f[2][7] = f[2][1] = f[2][3] = 1;
	f[3][7] = f[3][4] = f[3][2] = 1;
	f[4][3] = f[4][5] = 1;
	f[5][7] = f[5][6] = f[5][4] = 1;
	f[6][1] = f[6][7] = f[6][5] = 1;
	f[7][2] = f[7][6] = f[7][3] = f[7][5] = 1;//a,b,c,d,e,f,g分别对应1234567,用二维数组表示它们相邻 
	
	dfs(1);
	
	cout << ans;
	
	return 0;
}

 6、

简单题目了可以说,唯一值得注意的四舍五入要会写;

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

int main()
{
	int sum = 0 ,x = 0 ,y = 0;
	int n ;
	cin >> n;
	while (n --)
	{
		double a;
		cin >> a;
		sum ++;
		if (a >= 60) x ++;
		if (a >= 85) y ++;
	}
	
	double xx = x * 1.00000 / sum;
	double yy = y * 1.00000 / sum;
	
	if (xx / 1000 >= 0.005) xx += 0.01;
	if (yy / 1000 >= 0.005) yy += 0.01;
	
	printf("%.0lf" ,xx * 100);
	cout << '%' << endl;
	printf("%.0lf" ,yy * 100);
	cout << '%';
	
	return 0;
 } 

 7、

 字符串的应用,思路并不复杂,主要是考验代码的基本功

#include<bits/stdc++.h>
using namespace std;
int month[13] = {-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int date, ans1, ans2;
// 判断日期是否回文
bool check1(int date)
{
	string s = to_string(date);
	if (s[0] == s[7] && s[1] == s[6] && s[2] == s[5] && s[3] == s[4]) return true;
	return false;
}
// 判断日期是否满足 ABABBABA 型回文
bool check2(int date)
{
	string s = to_string(date);
	if (s[0] == s[2] && s[0] == s[5] && s[0] == s[7] && s[1] == s[3] && s[1] == s[4] && s[1] == s[6]) return true;
	return false;
}
int main()
{
	cin >> date;
	int y = date / 10000, m = date / 100 % 100, d = date % 100;
// 枚举合法日期,即枚举合法的年、月、日
	for (int i = y ; ; i ++ )
	{
		if (i % 400 == 0 || (i % 100 != 0 && i % 4 == 0)) month[2] = 29;
		else month[2] = 28;
		
		int j = (i == y) ? m : 1;
		
		for ( ; j <= 12 ; j ++ )
		{
			int k = (i == y && j == m) ? d + 1 : 1;
			for( ; k <= month[j] ; k ++)
			{
				int date = i * 10000 + j * 100 + k;
				
				if (check1(date) && ans1 == 0) ans1 = date;
				
				if (check2(date)) //当找到了 ABABBABA 型回文日期时,结束程序
					return cout << ans1 << '\n' << date << '\n', 0; 
			}
		}
	}	
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值