2021蓝桥杯省赛C/C++B组

1550:卡片
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
  printf("3181\n");
  return 0;
}
1551: 直线
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
{
int ans = 40257;
cout << ans << endl;
return 0;
}
1552:货物摆放
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
int main()
{
ll n = 2021041820210418;
int ans = 0;
ll k;
for (ll i = 1; i * i * i <= n; i++)
{
if (n % i == 0)
{
for (ll j = i; i * j * j <= n; j++)
{
if (n / i % j == 0)
{
k = n / i / j;
if (i == j && j == k)
ans++;
else if (i == j || i == k || j == k)
ans += 3;
else
ans += 6;
}
}
}
}
cout << ans << endl;
return 0;
}
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
cout << "2430" << endl;
}
1553: 路径
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int N = 2030;
ll edge[N][N];
int gcd(int a, int b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
int lcm(int a, int b)
{
int x = a * b;
return x / gcd(a, b);
}
int main()
{
memset(edge, 0x3f3f3f3f, sizeof(edge));
for (int i = 1; i <= 2021; i++)
{
for (int j = 1; j <= 2021; j++)
{
if (i == j)
edge[i][j] = 0;
else {
if (abs(i - j) <= 21)
{
edge[i][j] = lcm(i, j);
}
}
}
}
for (int k = 1; k <= 2021; k++)
{
for (int i = 1; i <= 2021; i++)
{
for (int j = 1; j <= 2021; j++)
{
if (edge[i][j] > edge[i][k] + edge[k][j])
{
edge[i][j] = edge[i][k] + edge[k][j];
}
}
}
}
cout << edge[1][2021];
return 0;
}
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
{
cout << "10266837" << endl;
return 0;
}
1555: 空间
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int main()
{
ll num = 256 / 32 * 1024 * 1024 * 8;
cout << num << endl;
}
1558:砝码称重
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1e5 + 10;
int a[N];
int w[110];
int main()
{
int n;
cin >> n;
memset(a, 0, sizeof(a));
a[0] = 1;
for (int i = 1; i <= n; i++)
cin >> w[i];
for (int i = 1; i <= n; i++)
{
for (int j = 100000; j >= w[i]; j--)
{
a[j] = max(a[j], a[j - w[i]]);
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= 100000 - w[i]; j++)
{
a[j] = max(a[j], a[j + w[i]]);
}
}
int ans = 0;
for (int i = 1; i <= 100000; i++)
{
ans += a[i];
}
cout << ans << endl;
return 0;
}
1561:括号序列

首先我们要知道要使得括号合法,左括号一定大于右括号的数量,

定义 f[i][j] 表示对于前 i 个字符,左括号数量比右括号数量多 j 个的添加括号方案数,先算出添加左括号的方案数,再从右到左算出添加右括号的方案数,最后两个相乘就是我们的结果。

#include<bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int N = 5100, mod = 1e9 + 7;
ll f[N][N];
char s[N];
int n;
ll solve()
{
memset(f, 0, sizeof(f));
f[0][0] = 1;
for (int i = 1; i <= n; i++)
{
if (s[i] == '(')
{
for (int j = 1; j <= n; j++)
{
f[i][j] = f[i - 1][j - 1];
}
}
else
{
f[i][0] = (f[i - 1][0] + f[i - 1][1]) % mod;
for (int j = 1; j <= n; j++)
{
f[i][j] = (f[i][j - 1] + f[i - 1][j + 1]) % mod;
}
}
}
for (int i = 0; i <= n; i++)
{
if (f[n][i]) return f[n][i];
}
return 0;
}
int main()
{
scanf("%s", s + 1);
n = strlen(s + 1);
ll x = solve();
reverse(s + 1, s + 1 + n);
for (int i = 1; i <= n; i++)
{
if (s[i] == '(')
s[i] = ')';
else
s[i] = '(';
}
ll y = solve();
cout << (x * y) % mod << endl;
return 0;
}
1563: 时间显示
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
int main()
{
int t;
ll n;
cin >> t;
while (t--)
{
int h, m, s;
cin >> n;
n = n / 1000;
s = n % 60;
n /= 60;
m = n % 60;
n /= 60;
h = n % 24;
printf("%02d:%02d:%02d\n", h, m, s);
}
return 0;
}
1564: 杨辉三角形

题目:寻找第一次出现N的位置。

本题杨辉三角每个位置对应的数相当于组合数C(i,j),同时可以知道当C(n,3)>=1e9时n>=1819,我们可以先暴力求解2000范围以内的,如果没有,再通过C(n,1),C(n,2)来寻找。

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll a[2010][2010];
void slove()
{
ll n;
cin >> n;
a[0][0] = 1;
for (int i = 1; i <= 2000; i++)
{
for (int j = 1; j <= i; j++)
{
a[i][j] = a[i - 1][j] + a[i - 1][j - 1];
if (a[i][j] == n)
{
cout << i * (i - 1) / 2 + j << endl;
return;
}
}
}
ll l = 1, r = n;
while (l < r)
{
ll mid = l + r >> 1;
if (mid * (mid - 1) >= n)
r = mid;
else
l = mid + 1;
}
ll ans = n * (n + 1) / 2 + 2;
if (r * (r - 1) / 2 == n)
{
ans = r * (r - 1) / 2 + 3;
}
cout << ans << endl;
}
int main()
{
int t;
cin >> t;
while (t--)
{
slove();
}
return 0;
}
1565: 双向排序

题目:总共有2个操作,一个是选定前 x 个数,使其降序,另一个是选定后 y 个数,使其升序。

如果连续给出同一种操作,且区间相邻或包含,则等效于操作一次最长的,一次实现多个操作。

如果操作交替进行,则排列将会逐渐有序,需要排序翻转的部分会越来越小。最终确定整个序列。

#include <bits/stdc++.h>  
#include <algorithm>
#define x first  
#define y second  
using namespace std;
typedef pair<int, int> PII;
const int N = 1e5+10;
int n, m, ans[N];
PII stk[N];
int main() 
{
cin >> n >> m;
int top = 0;
while (m--) 
{
int p, q; 
cin >> p >> q;
if (!p) 
{
while (top && stk[top].x == 0) 
q = max(q, stk[top--].y);
while (top >= 2 && stk[top - 1].y <= q) 
top -= 2; 
stk[++top] = { 0, q };
}
else if (top) 
{ 
while (top && stk[top].x == 1) 
q = min(q, stk[top--].y);
while (top >= 2 && stk[top - 1].y >= q) 
top -= 2;
stk[++top] = { 1, q };
}
}
int k = n, l = 1, r = n;
for (int i = 1; i <= top; i++) 
{
if (stk[i].x == 0) 
{
while (r > stk[i].y && l <= r) 
ans[r--] = k--;
}
else 
{
while (l < stk[i].y && l <= r) 
ans[l++] = k--;
}
if (l > r) 
break;
}
if (top % 2) 
{
while (l <= r) 
ans[l++] = k--;
}
else 
{
while (l <= r) 
ans[r--] = k--;
}
for (int i = 1; i <= n; i++)
cout << ans[i];
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值