第十一届蓝桥杯大赛软件类省赛第二场
第十一届蓝桥杯省赛大学B组试题
A题 门牌制作
思路:
统计1到2020号门牌的字符2的总个数.
#include <bits/stdc++.h>
using namespace std;
int main()
{
int sum = 0;// 计数
int a[4];// 存取个位 十位 百位 千位
for(int i = 1; i <= 2020; i++)
{
a[0] = i % 10;
a[1] = i % 100 / 10;
a[2] = i % 1000 / 100;
a[3] = i / 1000;
for(int k = 3; k >= 0; k--)
{
if(a[k] == 2)
sum++;
}
}
cout << sum;
return 0;
}
答案是 624
B题 跑步锻炼
求解代码:
#include <bits/stdc++.h>
using namespace std;
int GCD(int a, int b)
{
if(b == 0)
return a;
else
return GCD(b, a%b);
}
int main()
{
int sum = 0;
for(int i = 1; i <= 2020; i++)
for(int j = 1; j <= 2020; j++)
{
if(GCD(i,j) == 1)
sum++;
}
cout << sum;
return 0;
}
答案: 2481215
C题 蛇形填数
思路:
一般都会想到把对角线上的递推公式找出来,假设对角线上的元素都是\(a_n\)那么很明显每一个\(a_n\)都与\(n\)以及\(a_{n-1}\)有关系,并且应该是一次的.
其实此时可以推出来递推公式.
例如 \(a_4\) = 25 = \(4 \times 3 + 13\)
求解代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a = 1;
for(int i = 2; i <= 20; i++)
{
a = 4*(i-1) + a;
}
cout << a;
return 0;
}
D题 跑步锻炼
思路: 处理好每天天数的增加,月份年份增加,核心是day++,请参考代码注释.
#include <bits/stdc++.h>
using namespace std;
// 月份天数数组 先默认是平年
// M[0] 设置为0 是为了让月份和数组下标对应
int M[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int main()
{
int y = 2000, m = 1, d = 1, w = 6, ans = 0;
while(y != 2020 || m != 10 || d != 1)
{
d++; // d++一定要放在前面,下面有解释
w++;// 由于没先算第一天的 因此也要有 w++
// 判断平年闰年
if((y % 4 == 0 && y % 100 != 0) || y % 400 == 0)
M[2] = 29;
else
M[2] = 28;
w = w % 7; // 这样默认 0是周天 1是周一.....
if(d > M[m])
{
d = 1;
m++;
}
if(m > 12)
{
m = 1;
y++;
}
//月初或者周一多加一天
if(d == 1 || w == 1)
{
ans++;
}
ans++;
}
ans += 2; //加上第一天要跑2千米
cout << ans;
return 0;
}
为什么要把 d++, 放在while循环的前面的,这样的话岂不是相当于第一天的跑步里程没有加进去?所以放在while循环体的后面,岂不是更好??
答案是 不能放在后面,我们观察一下 while循环的结束条件,第11行,也就是当 y = 2020, m = 10, d = 1时循环终止.但是,循环终止的条件是在第 **24,25 **行达到的.,如果d++,在其下面的话,则恰好跳过了循环结束条件.d变成2了.
最终答案: 8879
E题 七段码
-
不正经解法
我们知道,所有灯发光的情况一共有$C_71+C_72+C_73+C_74+C_75+C_76 +C_7^7 = 127 $种可能,我们可以人工判断.....所以我们想办法,让计算机来画一个这样的图案:
具体细节请看代码:
// 全组合实现
// 关键字 栈 递归
#include <bits/stdc++.h>
using namespace std;
vector <int> s;
int count_numbers = 0;
// _
//|_|
//|_|
void draw_ejg(int i)
{
if(i == 0)
cout << " _\n";
if(i == 1)
cout << "|";
if(i == 2)
cout << "_";
if(i == 3)
cout << "|\n";
if(i == 4)
cout << "|";
if(i == 5)
cout << "_";
if(i == 6)
cout << "|\n";
}
void print(int n)
{
if(count_numbers == 0)
{
count_numbers++;
return;
}
count_numbers++;
cout << count_numbers-1 << ":" << endl;
// 利用子集数组,实现A的子集求解
for(int i = 0; i < n; i++)
{
if(s[i] == 1)
{
draw_ejg(i);
}
else
{
if(i == 3 or i == 6)
cout << "\n";
else
cout << " ";
}
}
cout << endl << endl;
}
void subsetting(int c, int n)
{
if(c <= n)
{
s.push_back(0);
subsetting(c+1, n);
s.pop_back();
s.push_back(1);
subsetting(c+1, n);
s.pop_back();
}
else
print(n);
}
int main()
{
subsetting(1,7);
return 0;
}
大家可以自行运行一下,,,然后就硬数,,,,,这是部分运行截图
我们可以得到答案:
- 正经解法
如果使用纯程序解法,其实也不难,创建连接矩阵,遍历查看点与点的连接情况.但我不会写.....
#include <bits/stdc++.h>
using namespace std;
vector <int> s;
vector <int> A;
int count_numbers = 127;
int flag = 0;
int adj[7][7] = {
{1,1,0,1,0,0,0},
{1,1,1,0,1,0,0},
{0,1,1,1,1,0,1},
{1,0,1,1,0,0,1},
{0,1,1,0,1,1,0},
{0,0,0,0,1,1,1},
{0,0,1,1,0,1,1}
};
void print(int n)
{
for(int i = 0; i < n; i++)
{
if(s[i] == 1)
A.push_back(i);
}
// print A
// for(int i = 0; i < A.size(); i++)
// cout << A[i];
// cout << endl;
A.clear();
}
void subsetting(int c, int n)
{
if(c <= n)
{
s.push_back(0);
subsetting(c+1, n);
s.pop_back();
s.push_back(1);
subsetting(c+1, n);
s.pop_back();
}
else
print(n);
}
int main()
{
cout << "hello world";
return 0;
}
F题 成绩统计
求解代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int exc = 0;
int pass = 0;
int score;
int n;
cin >> n;
int flag = n;
while(flag)
{
cin >> score;
if(score >= 60)
pass++;
if(score >= 85)
exc++;
flag--;
}
double pass_ac = double(pass)/double(n);
double exc_ac = double(exc)/double(n);
printf("%.2f\n%.2f", pass_ac, exc_ac);
}
G题 回文日期
求解代码:
#include <bits/stdc++.h>
using namespace std;
// 月份天数数组 先默认是平年
// M[0] 设置为0 是为了让月份和数组下标对应
int M[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
bool judge1(int y, int m, int d)
{
// 将 y m d 转化为一个数字
long long date = y*10000 + m*100 + d;
// 将这个数字转化为一个字符串
stringstream s;
s << date;
string date_str;
s >> date_str;
for(int i = 0; i < date_str.length()/2; i++)
{
if(date_str[i] != date_str[date_str.length()-1-i])
return 0;
}
cout << date_str << endl;
return 1;
}
bool judge2(int y, int m, int d)
{
// 将 y m d 转化为一个数字
long long date = y*10000 + m*100 + d;
// 将这个数字转化为一个字符串
stringstream s;
s << date;
string date_str;
s >> date_str;
if(date_str[0] == date_str[2] && date_str[2] == date_str[5] && date_str[5] == date_str[7]
&& date_str[1] == date_str[3] && date_str[3] == date_str[4] && date_str[4] == date_str[6])
{
cout << date_str;
return 1;
}
return 0;
}
int main()
{
int flag1 = 0;
int flag2 = 0;
long long date;
cin >> date;
// 提取出 年 月 日
int y = date / 10000;
int m = date % 10000 / 100;
int d = date % 100;
while((!flag1) || (!flag2))
{
d++;
// 判断平年闰年
if((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0))
M[2] = 29;
else
M[2] = 28;
if(d > M[m])
{
d = 1;
m++;
}
if(m > 12)
{
m = 1;
y++;
}
if(!flag1)
flag1 = judge1(y, m, d);
if(!flag2)
flag2 = judge2(y, m, d);
}
return 0;
}
H题 子串分值和
#include <bits/stdc++.h>
using namespace std;
string str;
int f(int i,int j)
{
int count_numbers = 0;
int uni = 1;
string flag = "";
int flag2;
string sub_str = str.substr(i,j+1);
for(int i = 0; i < sub_str.length(); i++)
{
for(int j = 0; j < flag.length(); j++)
{
if(sub_str[i] == flag[j])
{
uni = 0;
break;
}
}
if(uni)
{
count_numbers++;
flag += sub_str[i];
}
}
return count_numbers;
}
int main()
{
cin >> str;
int sum = 0;
for(int i = 0; i < str.length(); i++)
{
for(int j = i; j < str.length(); j++)
sum += f(i,j);
}
cout << sum;
return 0;
}
I题 平面切分
思路:对于一条直线,在它不是重边的前提下,如果与其它直线交点个数是0,则平面切分数加1,其次,与其它直线每产生一个不同的交点,则平面切分数又加1.
未完待续........
本文来自博客园,作者:CuriosityWang,转载请注明原文链接:https://www.cnblogs.com/curiositywang/p/14634881.html