第十四届蓝桥杯C++B组省赛
第十四届
A.日期统计(5分)
// 枚举 哈希表
#include <bits/stdc++.h>
using namespace std;
int ns[100] = {5, 6, 8, 6, 9, 1, 6, 1, 2, 4, 9, 1, 9, 8, 2, 3, 6, 4, 7, 7, 5, 9, 5, 0, 3, 8, 7, 5, 8, 1, 5,
8, 6, 1, 8, 3, 0, 3, 7, 9, 2, 7, 0, 5, 8, 8, 5, 7, 0, 9, 9, 1, 9, 4, 4, 6, 8, 6, 3, 3, 8, 5,
1, 6, 3, 4, 6, 7, 0, 7, 8, 2, 7, 6, 8, 9, 5, 6, 5, 6, 1, 4, 0, 1, 0, 0, 9, 4, 8, 0, 9, 1, 2,
8, 5, 0, 2, 5, 3, 3};
int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
set<int> res; // 哈希表去重
void check(int m, int d) // 月份 日期
{
if(m < 1 || m > 12 || d < 1 || d > days[m]) return;
res.insert(m * 100 + d);
}
int main()
{
// 先循环找出数字 2023
for(int a = 0; a < 100; a ++ ){
if(ns[a] != 2) continue;
for(int b = a + 1; b < 100; b ++ ){
if(ns[b] != 0) continue;
for(int c = b + 1; c < 100; c ++ ){
if(ns[c] != 2) continue;
for(int d = c + 1; d < 100; d ++ ){
if(ns[d] != 3) continue;
// 再循环找出 月份 天数
for(int i = d + 1; i < 100; i ++ )
for(int j = i + 1; j < 100; j ++ )
for(int k = j + 1; k < 100; k ++ )
for(int l = k + 1; l < 100; l ++ )
check(ns[i] * 10 + ns[j], ns[k] * 10 + ns[l]);
}
}
}
}
cout << res.size() << endl;
return 0;
}
B.01串的熵(5分)
// 枚举 模拟
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll H = 116259075798; // 原熵值为11625907.5798,为方便计算 * 10000
const ll N = 23333333;
bool check(ll x)
{
double p0 = 1.0 * x / N, p1 = 1 - p0;
ll h = 10000ll * (x * p0 * log2(p0) + (N - x) * p1 * log2(p1)); // 传入x值计算所得的信息熵
return H + h == 0;
}
// 由于01串长度N已知,可以依据公式依次枚举x直到返回正确熵值
int main()
{
for(ll x = 1; x <= N / 2; x ++ )
if(check(x)) cout << x << endl;
return 0;
}
C.冶炼金属(10分)
// ... ... 还行,过了99个数据
#include <bits/stdc++.h>
using namespace std;
=
int main()
{
int N, A, B, V; // N条冶炼记录,A个金属O经过转换率V冶炼出B个金属X
int vmax = 0, vmin = 0, Vmax = 0, Vmin = 0; // 更新最大/最小转换率 存放最终结果
cin >> N;
for(int i = 0; i < N; i ++ )
{
cin >> A >> B;
vmax = max(vmax, A / B); // 注:vmax可由输入A/B值得出一个适当的范围值
for(vmin = vmax / 2; vmin < vmax; vmin ++ )
{
if(A / vmax == B && A / vmin == B){
cout << vmin + 1 << " " << vmax << endl;
return 0;
}
}
}
return 0;
}
抽象
// 数学 整除 推导
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, a, b;
int vmin = 0, vmax = 2e9;
cin >> n;
for(int i = 0; i < n; i ++ )
{
cin >> a >> b;
vmax = min(vmax, a / b); // 不能大于每一个炉子的最大值 取min
vmin = max(vmin, a / (b + 1) +1); // 不能低于每一个炉子的最大值 取max
}
cout << vmin << " " << vmax << endl;
return 0;
}
D.飞机降落(10分)
// 暴搜
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, T; // 测试 每组降落n架飞机
int a[N][3]; // 存储每架飞机 最早降落时间 最迟降落时间 降落过程需要时间
bool st[N], flag; // st[i]标记第i驾飞机是否完成降落, flag 标记全部飞机是否完成降落
void dfs(int k, int last) // 当前已有k架飞机完成降落 上一架飞机降落完成时间last
{
if(k >= n){
puts("YES");
flag = true;
}
if(flag) return;
for(int i = 1; i <= n; i ++ ){
if(!st[i])
{
if(a[i][1] < last) return; // 当前飞机最迟降落时间<上一架飞机完成降落之前则无法降落,剪掉
st[i] = true;
if(a[i][0] > last) dfs(k + 1, a[i][0] + a[i][2]); // 最早降落时间在上一架飞机完成降落之后则等待,让其他飞机先降落
else dfs(k + 1, last + a[i][2]); // 否则上一驾飞机完成这一驾立马降落
st[i] = false; // 还原现场
}
}
}
int main()
{
cin >> T;
while(T -- )
{
cin >> n;
flag = false;
memset(st, 0, sizeof st); // 全部设置成未完成降落
for(int i = 1; i <= n; i ++ ){
cin >> a[i][0] >> a[i][1] >> a[i][2];
a[i][1] += a[i][0]; // 设置为最迟降落时间
}
dfs(0,0);
if(!flag) cout << "NO" << endl;
}
return 0;
}
E.接龙数列(15分)
F.岛屿个数(15分)
G.子串简写(20分)
H.整数删除(20分)
I.景区导游(20分)
第十三届
A.九进制转换十进制(5分)
#include <bits/stdc++.h>
using namespace std;
int main()
{
cout << 2 * 1 + 2 * 9 + 0 * 9 * 9 + 2 * 9 * 9 * 9 << endl;
return 0;
} // 1478
B.顺子日期(5分)
#include <bits/stdc++.h>
using namespace std;
const int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int main()
{
int ans = 0;
for(int i = 0; i <= 1; i ++ ){
for(int j = 0; j <= 9; j ++ ){
if(i * 10 + j > 12 || i * 10 + j < 1) continue;
for(int k = 0; k <= 3; k ++ ){
if(k * 10 > days[i * 10 + j]) continue;
for(int l = 0; l <= 9; l ++ ){
if((i + 1 == j && j + 1 == k) || (j + 1 == k && k + 1 == l)) ans ++;
}
}
}
}
cout << ans << endl;
return 0;
}// 22 错了,月份日期乱了
#include <bits/stdc++.h>
using namespace std;
const int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int main()
{
int ans = 0;
for(int i = 0; i <= 1; i ++ ){
for(int j = 0; j <= 9; j ++ ){
if(i * 10 + j > 12 || i * 10 + j < 1) continue;
for(int k = 0; k <= 3; k ++ ){
for(int l = 0; l <= 9; l ++ ){
if(k * 10 + l > days[i * 10 + j]) continue; // 关键
if((i + 1 == j && j + 1 == k) || (j + 1 == k && k + 1 == l)) ans ++;
}
}
}
}
cout << ans << endl;
return 0;
}// 正确答案:14
C.刷题统计(10分)
// 模拟
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ll a, b, n;
cin >> a >> b >> n;
ll x = n / (5 * a + 2 * b); // 计算所需星期数
n -= x * (5 * a + 2 * b); // 更新n为最后一个星期做题数
ll i = 0;
for(i = 0; i < 7; i ++ ) // 注意i不能 == 7
{
if(i <= 5 && i > 0) n -= a; // 从0开始枚举,否则当星期数正好时i为1退出循环容易多加1天
if(i == 6 && i == 7) n -= b;
if(n <= 0) break;
}
//cout << x << " " << i << endl; // 调试样例
cout << x * 7 + i << endl;
}
D.修剪灌木(10分)
//
#include <bits/stdc++.h>
using namespace std;
int main()
{
int N;
cin >> N;
int a[N + 10] = { 0 }, amax[N + 10] = { 0 };
for(int i = 1; i <= N; i ++ ) cin >> a[i];
for(int i = 1; i <= N; i ++ ){
amax[i] = max(a[i], 2 * (i - 1));
amax[i] = max(amax[i], 2 * (N - i));
}
for(int i = 1; i <= N; i ++ ) cout << amax[i] << endl;
return 0;
}
E.X进制减法