2024牛客寒假算法基础集训营2(F、K、I、J)

F.Tokitsukaze and Eliminate (hard)

题目:

解题思路:

对于总共有n个宝石,统计出不同的宝石有a个,从后往前取,则第一次取宝石可以取出a个不同的宝石,剩下不同的宝石有b个(b<=a),第二次再取出b个不同的宝石······最终统计一下次数即可。

代码如下:

#include <bits/stdc++.h>
#include <iostream>
#define int long long
#define endl '\n'
using namespace std;
signed main()
{   ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        int n,a[200005],sum=0,ans=0,k=0,j=0;
        map<int,int>b;
        map<int,int>c;    //这里使用数组会超时,所以要考虑stl容器
        cin>>n;
        for(int i=1;i<=n;i++)
            {cin>>a[i];
             if(b[a[i]]==0)sum++;    //统计不同宝石的总个数
             b[a[i]]++;}             //统计每个宝石的个数
        for(int i=n;i>=1;i--)
        {
            if(c[a[i]]==0)k++;    //统计不同宝石的个数
            c[a[i]]++;
            b[a[i]]--;
            if(b[a[i]]==0)j++;    //每当有宝石的个数为0时,总数要减去1
            if(k==sum)
                {sum-=j,j=0,ans++,k=0;
                 c.clear();    //清空}
        }
        cout<<ans<<endl;
    }
 	return 0;
}

K.Tokitsukaze and Password (easy)

题目:

解题思路:

此题可以直接暴力搜索,对a,b,c,d,_,进行整体考虑,最终会求出一个密码x,若满足题目所给条件及范围,则数量+1。

代码如下:

#include <bits/stdc++.h>
#include <iostream>
#define int long long
#define endl '\n'
using namespace std;
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        int n,y;
        string s;
        cin>>n;
        cin>>s>>y;
        int len=pow(10,n-1);    //求出这个位数的最小值,比如n=3时,最小值是100
        if(n==1)len=0;
        map<int,bool>k;
        for(int a=0; a<=9; a++)
        {
            for(int b=0; b<=9; b++)
            {
                for(int c=0; c<=9; c++)
                {
                    for(int d=0; d<=9; d++)
                    {
                        if(a==b||a==c||a==d||b==c||b==d||c==d)continue; //a,b,c,d不能相同
                        for(int _=0; _<=9; _++)
                        {
                            int x=0;
                            for(int i=0; i<n; i++)    //遍历出所有可能的结果
                            {
                                if(s[i]>='0'&&s[i]<='9')x=x*10+s[i]-'0';
                                else if(s[i]=='a')x=x*10+a;
                                else if(s[i]=='b')x=x*10+b;
                                else if(s[i]=='c')x=x*10+c;
                                else if(s[i]=='d')x=x*10+d;
                                else x=x*10+_;
                                if(x>=len&&x<=y&&x%8==0)    //若满足题目条件
                                    k[x]=1;
                            }
                        }
                    }
                }
            }
        }
        cout<<k.size()<<endl;
    }
    return 0;
}

 I.Tokitsukaze and Short Path (plus)

题目:

1<=T<=2\cdot 10^{5}(T组测试数据)

1<=N<=2\cdot 10^{5}(表示完全图G的顶点数量)

1<=a_{i}<=2\cdot 10^{5}(表示完全图G的每个顶点的值)

第二组测试数据:

3
10 1 100

解题思路:

对于此题使用最短路会超时,所以要先找规律,边权值为取两个点之间权值较大的那个权值的两倍。以下对第二组数据进行分析:

题目所求解为1->2,1->3,2->3,2->1,3->1,3->2,对此只需要求出前一半的值最后再乘上2就可以。接下来再对前一半进行分析:首先要对顶点进行排序,1->2取值为20,1->3取值为200,2->3取值为200,总结得顶点1的次数为0,顶点2的次数为1,顶点3的次数为2,得到公式sum+=a[i]*(i-1)*2;

代码如下:

#include <bits/stdc++.h>
#include <iostream>
#define int long long
#define endl '\n'
using namespace std;
signed main()
{   ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        int n,a[200005],sum=0;
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        sort(a+1,a+n+1);
        for(int i=n;i>=2;i--)
            sum+=a[i]*(i-1)*2;
        cout<<sum*2<<endl;
    }
 	return 0;
}

J.Tokitsukaze and Short Path (minus)

题目:

解题思路:

此题与上一题解法类似,只不过边权值为取两个点之间权值较小的那个权值的两倍。

对样例分析得到1->3取值有两种情况,一是直接取值,另一个是经过最小值点。

代码如下:

#include <bits/stdc++.h>
#include <iostream>
#define int long long
#define endl '\n'
using namespace std;
signed main()
{   ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        int n,a[200005],sum=0;
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        sort(a+1,a+n+1);
        for(int i=1;i<n;i++)
            sum+=min(a[1]*4,a[i]*2)*(n-i);
        cout<<sum*2<<endl;
    }
 	return 0;
}

相关推荐

  1. 2024寒假算法基础集训1 D数组成鸡

    2024-02-11 17:06:01       61 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-11 17:06:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-11 17:06:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-02-11 17:06:01       87 阅读
  4. Python语言-面向对象

    2024-02-11 17:06:01       96 阅读

热门阅读

  1. django中自定义视图样式

    2024-02-11 17:06:01       52 阅读
  2. 计算机网络相关题目及答案(第七章)

    2024-02-11 17:06:01       49 阅读
  3. Shell - 学习笔记 - 2.10 - Shell字符串截取

    2024-02-11 17:06:01       52 阅读
  4. MySQL进阶查询篇(7)-触发器的创建和使用

    2024-02-11 17:06:01       56 阅读
  5. 【Rust日报】2024-02-10 扩展 Rust Effect 系统

    2024-02-11 17:06:01       49 阅读
  6. 计算机视觉主要知识点

    2024-02-11 17:06:01       47 阅读
  7. P6359 [CEOI2018] Cloud computing 题解

    2024-02-11 17:06:01       46 阅读
  8. 笔趣阁小说批量爬取脚本代码

    2024-02-11 17:06:01       53 阅读
  9. 906. 区间分组(贪心)

    2024-02-11 17:06:01       45 阅读