Codeforces Round #617 (Div. 3) Feb/04/2020 22:35UTC+8

比赛链接 https://codeforces.com/contest/1296
比赛记录 https://blog.csdn.net/cheng__yu_/article/details/105395197

C. Yet Another Walking Robot(记录路径)

在这里插入图片描述
题意:删除其中一段使得路径不变
思路:拿map记录一下路径

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e6+10,inf=1e9;

int t,n;
string s;
map<pair<int,int>,int> mp;

int main()
{
    cin>>t;
    while(t--)
    {
        mp.clear();
        cin>>n>>s;
        int nx=0,ny=0;
        int ansr=inf,ansl=-inf;
        int l=inf,r=inf;
        mp[{0,0}]=-1;
        for(int i=0;i<n;++i)
        {
            if(s[i]=='L') nx--;
            else if(s[i]=='R') nx++;
            else if(s[i]=='U') ny++;
            else if(s[i]=='D') ny--;
            //printf("nx=%d ny=%d\n",nx,ny);
            if(mp.count({nx,ny}))
            {
                l=mp[{nx,ny}]+1;
                r=i;
                if(r-l<ansr-ansl)
                    ansr=r,ansl=l;
                mp[{nx,ny}]=i;
            }
            else mp[{nx,ny}]=i;
        }
        if(l==inf) puts("-1");
        else cout<<ansl+1<<" "<<ansr+1<<"\n";

    }
    return 0;
}

D. Fight with Monsters

在这里插入图片描述
题意:你的攻击力为a,对手攻击力为 b。击杀怪物可以获得一分,你可以选择让对手跳过攻击k次,问最多能够击杀几只怪物
思路:拿余数排个序,贪心的拿

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+10,inf=1e9;

int n,a,b,k;
int h[maxn];

int main()
{
    cin>>n>>a>>b>>k;
    for(int i=1;i<=n;++i)
    {
        cin>>h[i];
        h[i]%=(a+b);
        if(h[i]==0) h[i]=a+b;
    }
    sort(h+1,h+1+n);
    int ans=0;
    for(int i=1;i<=n;++i)
    {
        if(a>=h[i]) ans++;
        else
        {
            int t=(h[i]-1)/a;
            if(t<=k) ans++,k-=t;
        }
    }
    cout<<ans<<"\n";
    return 0;
}

E2. String Coloring (hard version)(贪心)

在这里插入图片描述
题意:给定一个字符串染色,不同颜色的相邻字符可以交换,最终使得字符串从小到大排。最少需要几种染色以及染色方案
思路:每次只需要考虑当前字符前面比它大的字符。小的字符总是能够优先一步交换到前面

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+10,inf=1e9;

int n;
string s;

int main()
{
    cin>>n>>s;
    s="0"+s;
    string t;
    vector<int> ans;
    for(int i=1;i<=n;++i)
    {
        int j;
        for(j=0;j<t.size();++j)
        {
            if(t[j]<=s[i])
            {
                t[j]=s[i];
                ans.push_back(j+1);
                break;
            }
        }
        if(j==t.size())
        {
            t.push_back(s[i]);
            ans.push_back(j+1);
        }
    }
    cout<<t.size()<<"\n";
    for(auto i : ans)
        cout<<i<<" ";
    return 0;
}

F. Berland Beauty(边权赋值)

在这里插入图片描述
题意:给边赋值,使得路径上边权的最小值满足条件
思路:路径上的最小值只需要出现一次即可。每次给路径上的边权做更新时,需要取最大值,因为需要当前做更新的路径的最小值。最后check一下,路径最小值是不是正确的。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=5000+10,inf=1e9;

int n,m;
vector<pair<int,int> > e[maxn];
int to[maxn],lim[maxn],ans[maxn];
vector<int> path[maxn];

bool dfs(int u,int fa,int id)
{
    if(u==to[id]) return true;
    for(auto i : e[u])
    {
        int v=i.first;
        int p=i.second;
        if(v==fa) continue;
        if(dfs(v,u,id))
        {
            ans[p]=max(ans[p],lim[id]);
            path[id].push_back(p);
            return true;
        }
    }
    return false;
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n-1;++i)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        e[u].push_back({v,i});
        e[v].push_back({u,i});
    }
    scanf("%d",&m);
    for(int i=1;i<=m;++i)
    {
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        to[i]=v;
        lim[i]=w;
        dfs(u,0,i);
    }
    bool ok=true;
    for(int i=1;i<=m;++i)
    {
        int mi=inf;
        for(auto v : path[i])
            mi=min(mi,ans[v]);
        if(mi!=lim[i])
        {
            ok=false;
            break;
        }
    }
    if(!ok) puts("-1");
    else
    {
        for(int i=1;i<=n-1;++i)
            printf("%d%c",max(1,ans[i]),i==n-1?'\n':' ');
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值