Codeforces Round #603(div.2)

A题:https://codeforces.com/contest/1263/problem/A

题意:这道题的话,他给你三种糖果,每种糖果有r,g,b颗,然后你每天只吃2种糖果,但是这两种糖果是不同的,你不能吃相同的糖果。
思路:推导一下的话,因为这三种糖果的颗数不同,也没有什么特别的规律,所以我们就把它排序,从小到大。现在顺序是r<g<b。如果r+g<b,那么只能吃r+g天;要是r+g>b的话,就可以是 (r+g+b)/2 天。

AC代码:

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
ll a[5];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
     for(int i=1;i<=3;i++)
            cin>>a[i];
            sort(a+1,a+4);
     cout<<min(a[1]+a[2],(a[1]+a[2]+a[3])/2)<<endl;
    }
    return 0;
}

B题:https://codeforces.com/contest/1263/problem/B

题意:这道题的话,是给你很多个PIN码,每个PIN码是四位,然后每个PIN码可能是相同的,也可能是不同的,问你最少需要多少次,可以把给你的PIN码都变成不同的,每次可以改变一个PIN码的一位数。
思路:思路的话,因为n<10,所以我们很容易就想到最多需要10次来改变这个PIN码,而且每个PIN码都可以改变,所以就判断一下,如果需要改变,依次改变下去就好了。

AC代码:

#include <bits/stdc++.h>
using namespace std;
string s[20];
int n;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n;
        map<string,int>q;
        for(int i=0; i<n; i++)
        {
            cin>>s[i];
            q[s[i]]++;
        }
        int ans=0;
        for(int i=0; i<n; i++)
        {
            if(q[s[i]]==1)
                continue;
            ans++;
            q[s[i]]--;
            for(char j='0'; j<='9'; j++)
            {
                s[i][0]=j;
                if(q[s[i]]==0)
                {
                    q[s[i]]++;
                    break;
                }
            }
        }
        cout<<ans<<endl;
        for(int i=0; i<n; i++)
            cout<<s[i]<<endl;
    }
    return 0;
}

C题:https://codeforces.com/contest/1263/problem/C

题意:这道题的话,初看这道题,是给你一个数,找到它从1到它本身的所有除数,而且除数要四舍五入到最低(且不能重复)。
思路:然后很容易就想到枚举1~n,但这样做的话就t了,因为范围是1~10^9。
所有我们用到分块的思想,推导样例,会发现n/i和n/(n/i)所得的数是一样的,而且还能减少枚举次数,优化时间复杂度。
然后因为输出的时候是从小到大输出。
所以我们用栈的特点,后进先出,这样可以实现从小到大输出。
关于分块,可以看看这篇文章:https://blog.csdn.net/gdhy9064/article/details/90112836

AC代码:

#include <bits/stdc++.h>
typedef long long ll;
const int maxx=1010;
const int inf=0x3f3f3f3f;
using namespace std;
int main()
{
    ll t,n;
    cin>>t;
    while(t--)
    {
        cin>>n;
        stack<ll>q;
        ll ans=0;
        for (ll i=1; i<=n; i=ans+1)
        {
            if(n/i!=0)
                ans=min(n,n/(n/i));
            q.push(n/i);
        }
        cout<<q.size()+1<<endl;
        cout<<0<<" ";
        while(!q.empty())
        {
            cout<<q.top()<<" ";
            q.pop();
        }
        cout<<endl;
    }
    return 0;
}

D题:https://codeforces.com/contest/1263/problem/D

题意:这道题的话,给你一些字符串,它们是进入系统的密码。而且它们之间有转化关系,比如a=b,那么a,b,ab都是相等的,若a=c,那么c=b。现在给你n个字符串,找到最少需要几次才能使用这些字符串来进入系统。
思路:这道题的大概思路就是,因为字母之间有对应的转化关系。所以我们用并查集来维护这个查找,把n个字符串中,是a的对应在一起,是b的对应在一起。依次对应,看看有多少个对应,就是题意要求的最少需要几次的数量。

AC代码:

#include <bits/stdc++.h>
typedef long long ll;
const int maxx=300010;
const int inf=0x3f3f3f3f;
using namespace std;
int n;
int pre[maxx];
string s[maxx];
int getf(int x)
{
    if(x==pre[x])
        return x;
    pre[x]=getf(pre[x]);
    return pre[x];
}
int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>s[i];
    }
    for(int j=1; j<=n+26; j++)
    {
        pre[j]=j;
    }
    for(int i=1; i<=n; i++)
    {
        for(int j=0; j<s[i].size(); j++)
        {
            pre[getf(i)]=pre[getf(n+s[i][j]-'a'+1)];
        }
    }
    int ans=0;
    set<int>vis;
    for(int i=1; i<=n; i++)
    {
        if(!vis.count(getf(i)))
        {
            ans++;
            vis.insert(getf(i));
        }
    }
    cout<<ans<<endl;
    return 0;
}
发布了204 篇原创文章 · 获赞 16 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43846139/article/details/103464053
今日推荐