头像

五星市民欧某人




离线:1小时前


最近来访(79)
用户头像
ʕˑʔ_9
用户头像
夏が終わる...
用户头像
奇点lzy
用户头像
catsayer_9
用户头像
InvolutionZ
用户头像
朱柏霖
用户头像
Wiselnn
用户头像
陈信长
用户头像
Codemon
用户头像
21KINGDMG
用户头像
夏花花花花花
用户头像
苍茫得胖帅
用户头像
嘶锅咦
用户头像
天堂已经死了
用户头像
L_H_R
用户头像
TheBlaze
用户头像
唯手熟尔hh
用户头像
codingxiaobai
用户头像
15358022392
用户头像
Kirito_9


#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

int a[105]; // 标记

int main()
{
    string s;
    cin >> s;
    for (int i=0; i<s.length(); i++)
    {
        if (s[i] == ')')   // 找到了右括号
        {
            for (int j=i-1; j>=0; j--)
            {
                if (s[j] == '(' and a[j] == 0)   // 找到了没被匹配过的左括号且匹配成功
                {
                    a[i] = a[j] = 1;
                    break;
                }
                else if (s[j] == '[' and a[j] == 0) break; // 找到了左括号但匹配失败
            }
            // 找不到左括号,不做任何操作
        }
        // 下面同理
        else if (s[i] == ']')
        {
            for (j=i-1; j>=0; j--)
            {
                if (s[j] == '[' and a[j] == 0)
                {
                    a[i] = a[j] = 1;
                    break;
                }
                else if (s[j] == '(' and a[j] == 0) break;
            }
        }
    }
    for (i=0; i<s.length(); i++)
    {
        if (a[i] == 0)   // 没有匹配则成对输出
        {
            if (s[i] == '(' or s[i] == ')') cout << "()";
            else cout << "[]";
        }
        else cout << s[i]; // 匹配成功则直接输出
    }
    return 0;
}



#include <iostream>
#include <stack>
using namespace std;

const int N = 100005;
int q, n;
stack<int> pu;
int a[N], b[N];

int main()
{
    cin >> q;
    while (q -- )
    {
        cin >> n;
        for (int i = 1; i <= n; i ++ ) cin >> a[i];
        for (int i = 1; i <= n; i ++ ) cin >> b[i];

        int zd = 1;
        for (int i = 1; i <= n; i ++ )
        {  
            pu.push(a[i]);
            while(b[zd] == pu.top())//栈顶元素与b当前元素相等 && 栈不为空,出栈
            {
                zd ++, pu.pop();
                if(pu.empty()) break;
            }
        }

        if(pu.empty()) cout << "Yes" << endl;//如果为空则说明序列b正确
        else cout << "No" << endl;
        while(!pu.empty()) pu.pop();//记得清空,下次还得用
    }
    return 0;
}



#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 100010;
int i, r, t, s;
int n, k;
int w[300005], x[300005], y[300005];
//w[i] 表示当前国籍为i的人的数量
//x[i] 表示i个人的国籍
//y[i] 表示第i组的时间

int main()
{
    cin >> n;
    while (n -- )
    {
        cin >> t >> k;//时间 人数
        while(k --)
        {
            y[++ r] = t;//时间
            cin >> x[r];
            if(! w[x[r]]) s ++;//当前这个人的国籍没人,答案++
            w[x[r]] ++;//国籍为x[r]的人的数量++
        }

        while(t - y[i] >= 86400)//t表示目前时间,y[i]表示第i的人到达时间
        //当y[i]这个人到达时间与目前时间已经超过一天时
            if(! --w[x[i ++]]) s --;
        /*
        w[x[i]]--;//国籍为当前这个人的国籍的人的数量-1
        if(!w[x[i]])s--;//如果当前这个人的国籍没人,那么答案-1
        i++;//换下一个人
        */
        //而i不用重置是因为题目输入的t全都是升序排列,所以可以依次取下一个人
        cout << s << endl;//最后输出答案
    }
    cout << r;
    return 0;
}


活动打卡代码 AcWing 4078. 01串

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 100010, MOD = 1e9 + 7;
int t, k;
int f[N];

int main()
{
    cin >> t >> k;
    f[0] = 1;
    for (int i = 1; i < N; i ++ )
    {
        f[i] = f[i - 1];
        if(i >= k) f[i] = (f[i] + f[i - k]) % MOD;
    }

    for (int i = 1; i < N; i ++ ) f[i] = (f[i] + f[i - 1]) % MOD;

    while (t -- )
    {
        int l, r;
        cin >> l >> r;
        cout << (f[r] - f[l - 1] + MOD) % MOD << endl;
    }
    return 0;
}


活动打卡代码 AcWing 4077. k显性字符

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

//k = 所有字符c的最大间隔,特判开头结尾
const int N = 100010, M = 26;
int n;
char str[N];
int last[M], d[M];//last 上一个字母位置,d 每个字母最大间隔

int main()
{
    scanf("%s", str + 1);
    n = strlen(str + 1);

    for (int i = 1; i <= n; i ++ )
    {
        int x = str[i] - 'a';
        d[x] = max(d[x], i - last[x]);
        last[x] = i;
    }

    for (int i = 0; i < 26; i ++ )
        d[i] = max(d[i], n + 1 - last[i]);

    int res = N + 1;
    for (int i = 0; i < 26; i ++ )
        res = min(res, d[i]);

    cout << res;
    return 0;
}



题目描述

小可可的学校信息组总共有n 个队员,每个人都有一个实力值a[i]a[i]。现在,一年一度的编程大赛就要到了,小可可的学校获得了若干个参赛名额,教练决定把学校信息组的nn 个队员分成若干个小组去参加这场比赛。

但是每个队员都不会愿意与实力跟自己过于悬殊的队员组队,于是要求分成的每个小组的队员实力值连续,同时,一个队不需要两个实力相同的选手。举个例子:[1, 2, 3, 4, 5][1,2,3,4,5]是合法的分组方案,因为实力值连续;[1, 2, 3, 5][1,2,3,5]不是合法的分组方案,因为实力值不连续;[0, 1, 1, 2][0,1,1,2]同样不是合法的分组方案,因为出现了两个实力值为1 的选手。

如果有小组内人数太少,就会因为时间不够而无法获得高分,于是小可可想让你给出一个合法的分组方案,满足所有人都恰好分到一个小组,使得人数最少的组人数最多,输出人数最少的组人数的最大值。

注意:实力值可能是负数,分组的数量没有限制。

样例

输入:
7
4 5 2 3 -4 -3 -5
输出;
3

说明

提示
【样例解释】 分为2 组,一组的队员实力值是{4, 5, 2, 3},另一组是{-4, -3, -5},其中最小的组人数为3,可以发现没有比3 更优的分法了。

基本思路:

把每一个组看成一个队列。我们只要关心的是队尾每次插入的元素是什么就行(每次存入最后一个元素就行)。
将n个数排序,从头到尾扫一遍,每次扫到一个数,就看一看现有的组(队列)中有没有末尾是该数-1的,有就插入进去,该组数量+1。
直到扫完,输出最小组数的长度。
每次选队列时,为了增高平均水平当然是加给最短的那个,如果没有符合要求的,新开一个队列。

#include <iostream>
#include <algorithm>
using namespace std;

const int N = 100005;
int n;
int a[N];
int last[N], length[N];

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++ ) cin >> a[i];

    sort(a + 1, a + n + 1);

    int count = 0;
    for (int i = 1; i <= n; i ++ )//遍历所有队员
    {
        bool flag = 0;
        int reg = 0;
        int maxn = 1e9;

        for (int j = 1; j <= count; j ++ )//遍历已经分的组
            if(last[j] == a[i] - 1 && length[j] < maxn)//找到可以放第i个数的组(多组满足条件时,选人员最少的组)
            {
                maxn = length[j];//该组人数
                reg = j;
                flag = 1;//找到标记
            }

        if(flag)//如果找到
        {
            last[reg] = a[i];//该组最后一个队员变为a[i]
            length[reg] ++;//该组人数增加1
        }
        else//如果没有找到,建新的组 
        {
            last[++ count] = a[i];
            length[count] = 1; 
        }
    }    

    int ans = 1000100;
    for(int i = 1;i <= count; i ++ )
        ans = min(ans, length[i]);
    cout<< ans;
    return 0;
}


分享 近期计划

近期计划:

1.算法基础课DP部分

2.C++语法基础课STL库函数等内容

3.《算法竞赛进阶指南》打卡活动

4.杂题选讲leetcode题目



活动打卡代码 AcWing 9. 分组背包问题

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 110;

int n, m;
int v[N][N], w[N][N], s[N];
int f[N];

int main()
{
    cin >> n >> m;

    for(int i = 1; i <= n; i ++ )
    {
        cin >> s[i];
        for(int j = 0; j < s[i]; j ++ )
            cin >> v[i][j] >> w[i][j];
    }

    for(int  i = 1; i <= n; i ++ )
        for(int  j = m; j >= 0; j --)
            for(int  k = 0; k < s[i]; k ++ )
                if(v[i][k] <= j)//只选一个
                    f[j] = max(f[j], f[j - v[i][k]] + w[i][k]);

    cout << f[m];
    return 0;
}


活动打卡代码 AcWing 5. 多重背包问题 II

01优化 + 二进制优化

#include <iostream>
#include <algorithm>
using namespace std;

const int N = 20005;
int n, m;
int v[N], w[N];
int f[N];

int main()
{
    cin >> n >> m;

    int cnt = 0;
    for (int i = 0; i < n; i ++ )
    {
        int a, b, s;
        cin >> a >> b >> s;

        int k = 1;
        while(k <= s)
        {
            cnt ++;
            v[cnt] = (k * a);
            w[cnt] = (k * b);
            s -= k;
            k *= 2; 
        }
        if(s > 0)
        {
            cnt ++;
            v[cnt] = (a * s);
            w[cnt] = (b * s);
        }
    }
    n = cnt;
    for (int i = 1; i <= n; i ++ )
        for (int j = m; j >= v[i]; j -- )
            f[j] = max(f[j], f[j - v[i]] + w[i]);

    cout << f[m];
    return 0;
}


活动打卡代码 AcWing 4. 多重背包问题

类比完全背包

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 110;
int n, m;
int v[N], w[N], s[N];
int f[N][N];

int main()
{
    cin >> n >> m;

    for (int i = 1; i <= n; i ++ ) cin >> v[i] >> w[i] >> s[i];

    for (int i = 1; i <= n; i ++ )
        for (int j = 0; j <= m; j ++ )
            for (int k = 0; k <= s[i] && k * v[i] <= j; k ++ )//数量不能超过指定的数量 & 小于给定的体积
            f[i][j] = max(f[i][j], f[i - 1][j - k * v[i]] + k * w[i]);

    cout << f[n][m];
    return 0;
}