2018蓝桥杯C++B组省赛

乘积尾零

数这些数的因子中有多少对2和5即可

#include<iostream>
 
#include<cstring>
#define int long long
using namespace std;
 
signed main()
{
    cout << "31" << endl;
}

全球变暖

用并查集求连通块,再找没去被淹没的点,根据连通块分析答案。

#include<iostream>
 
#include<cstring>
#include<set>
#define int long long
using namespace std;
const int N = 1e3 + 10;
int fa[N * N];
char map[N][N];
int find(int x)
{
    return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void merge(int a, int b)
{
    int faa = find(a), fbb = find(b);
    if (faa == fbb) return;
    else fa[fbb] = faa;
}
void solve()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
        {
            cin >> map[i][j];
            fa[i + (j - 1) * n] = i + (j - 1) * n;
        }
    set<int> ans, sum;
    for (int i = 2; i < n; i++)
        for (int j = 2; j < n; j++)
        {
            if (map[i][j] == '#')
            {
                if (map[i][j + 1] == '#') merge(i + (j - 1) * n, i + j * n);
                if (map[i + 1][j] == '#') merge(i + (j - 1) * n, i + (j - 1) * n + 1);
            }
        }
    for(int i=2;i<n;i++)
        for (int j = 2; j < n; j++)
        {
            if (map[i][j] == '#')
            {
                if (map[i - 1][j] == '#' && map[i][j + 1] == '#' && map[i][j - 1] == '#' && map[i + 1][j] == '#') ans.insert(find(i + (j - 1) * n));
                sum.insert(find(i + (j - 1) * n));
            }
             
        }cout << sum.size() - ans.size()<< endl;
}
signed main()
{
    solve();
}

第几天

直接算

#include<iostream>
#include<cstring>
#include<set>
#define int long long
using namespace std;
 
void solve()
{
    int ans = 31 + 29 + 31 + 30 + 4;
        cout << ans << endl;
}
signed main()
{
    solve();
}

明码

用代码模拟出来后所给信息是九的九次方是多少?

输出qmi(9,9)即可

#include<iostream>
#include<cstring>
#include<set>
#define int long long
using namespace std;
 
int qmi(int a, int b)
{
    int res = 1;
    while (b)
    {
        if (b & 1) res = res * a;
        a = a * a;
        b >>= 1;
    }
    return res;
}
void solve()
{
    cout << qmi(9, 9) << endl;
}
signed main()
{
    solve();
}

测试次数

动态规划,把dp[i][j]表示为从剩下i层j部手机是的最佳策略最坏情况。

所以如果手机摔坏了,就会向下更新一层,用下一层的状态来转移

如果没摔坏就说明还剩n-i层没有测试,用dp[n-i][j]的状态来转移

#include<iostream>
#include<cstring>
#include<set>
#define int long long
using namespace std;
const int N = 1e3 + 10;
int f[N][4];
void solve()
{
    int n = 1000, m = 3;
    for (int i = 1; i <= n; i++)
        f[i][1] = i;
    for (int j = 2; j <= m; j++)
    {
        for (int i = 1; i <= n; i++)
        {
            f[i][j] = 2e9 + 10;
            for (int k = 1; k <= i; k++)
            {
                f[i][j] = min(f[i][j], max(f[i - k][j], f[k - 1][j - 1]) + 1);
            }
        }
    }
    cout << f[n][m] << endl;
     
}
signed main()
{
    solve();
}
 

递增三元组

通过b数组,向上找最后一个小于b[i]的位置,向下找第一个大于b[i]的位置

#include<iostream>
#include<cstring>
#include<set>
#include<algorithm>
#define int long long
using namespace std;
const int N = 1e5 + 10;
int a[N], b[N], c[N];
int n;
int searcha(int x)
{
    int l = 1, r = n;
    while (l < r)
    {
        int mid = 1 + l + r >> 1;
        if (a[mid] >= x) r = mid - 1;
        else l = mid;
    }
    if (a[l] >= x) return 0;   
    return l;
}
int searchc(int x)
{
    int l = 1, r = n;
    while (l < r)
    {
        int mid = l + r >> 1;
        if (c[mid] <= x) l = mid + 1;
        else r = mid;
    }
    if (c[l] <= x) return 0; 
    return (n - l + 1);
}
void solve()
{
    int res = 0;
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];
    for (int i = 1; i <= n; i++) cin >> b[i];
    for (int i = 1; i <= n; i++) cin >> c[i];
    sort(a + 1, a + 1 + n);
    sort(b + 1, b + 1 + n);
    sort(c + 1, c + 1 + n);
    for (int i = 1; i <= n; i++)
    {
        res += searcha(b[i]) * searchc(b[i]);
    }
    cout << res << endl;
}
signed main()
{
    solve();
}
 

日志统计

先用set和vector分别存放输入和帖子编号,排个序,之后遍历set(帖子编号),滑动长度为k的窗口,如果窗口所包含的时间差值小于d,就说明是热帖。

#include<iostream>
#include<cstring>
#include<set>
#include<algorithm>
#include<queue>
#include<vector>
#define int long long
using namespace std;
const int N = 1e5 + 10;
int n, d, k;
vector<int> q[N];
set<int> s;
void solve()
{
    cin >> n >> d >> k;
    for (int i = 1; i <= n; i++)
    {
        int ts, id;
        cin >> ts >> id;
        q[id].push_back(ts);
        s.insert(id);
    }
    for (auto t : s)
    {
        int sz = q[t].size();
        if (sz < k) continue;
        sort(q[t].begin(), q[t].end());
        for (int j = 0; j <= sz - k; j++)
        {
            if (q[t][j + k - 1] - q[t][j] < d)
            {
                cout << t << endl;
                break;
            }
        }
    }
     
}
signed main()
{
    solve();
}

乘积最大

对k分类讨论,如果k是奇数,就取一个最大值,然后进入偶数的情况(这里要注意是否是全为负数)

偶数情况下,每次都从左侧或右侧取一对乘积大的数,直到取完k/2对。

如果是全负,且k是奇数,在取偶数的时候需要反着取乘积小的。还有就是注意取模运算。

#include<iostream>
#include<cstring>
#include<set>
#include<algorithm>
#include<queue>
#include<vector>
#define int long long
using namespace std;
const int N = 1e5 + 10, mod = 1000000009;
int n, k;
int a[N];
void solve()
{
    int cnt = 0, res = 1;
    int ans = 1, flag = 1;
    cin >> n >> k;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    sort(a + 1, a + 1 + n);
    if (k % 2)//奇数
    {
        if (a[n] < 0) flag = -1;
        ans = a[n], n--, k--;
    }
    int l = 1, r = n;
    while (k)
    {
        int x = a[l] * a[l + 1], y = a[r] * a[r - 1];
        if (x * flag > y * flag)
        {
            ans = x % mod * ans % mod;
            l += 2;
        }
        else
        {
            ans = y % mod * ans % mod;
            r -= 2;
        }
        k -= 2;
    }
    cout << ans << endl;
}
signed main()
{
    solve();
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值