Codeforces Round #823 (Div. 2) A-C题解

本文介绍了两个计算机科学竞赛题目,涉及最小化成本和时间的问题。第一题是关于摧毁行星的最经济策略,通过使用两种不同机器以最低费用清除障碍。第二题涉及在一条直线上安排会议,寻找使所有人到达会场总时间最短的点。解决方案包括二分查找法。第三题是关于数字字符串操作,找到通过删除和插入数字得到字典序最小字符串的方法。
摘要由CSDN通过智能技术生成

前言:很久都没参加过cf的比赛了,主要是这几天上课特别累,然后一直在刷acwing,今天要机测了就抽出空来写一篇吧。

 

A. Planets

One day, Vogons wanted to build a new hyperspace highway through a distant system with nn planets. The ii-th planet is on the orbit aiai, there could be multiple planets on the same orbit. It's a pity that all the planets are on the way and need to be destructed.

Vogons have two machines to do that.

  • The first machine in one operation can destroy any planet at cost of 11 Triganic Pu.
  • The second machine in one operation can destroy all planets on a single orbit in this system at the cost of cc Triganic Pus.

Vogons can use each machine as many times as they want.

Vogons are very greedy, so they want to destroy all planets with minimum amount of money spent. Can you help them to know the minimum cost of this project?

Input

The first line contains a single integer tt (1≤t≤1001≤t≤100) — the number of test cases. Then the test cases follow.

Each test case consists of two lines.

The first line contains two integers nn and cc (1≤n,c≤1001≤n,c≤100) — the number of planets and the cost of the second machine usage.

The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1001≤ai≤100), where aiai is the orbit of the ii-th planet.

Output

For each test case print a single integer — the minimum cost of destroying all planets.

 思路:简单题,不说了直接上代码。

#include <bits/stdc++.h>
using namespace std;
const int N=110;
int a[N];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,c;
        memset(a,0,sizeof(a));
        scanf("%d %d",&n,&c);
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            a[x]++;
        }
        int ans=0;
        for(int i=1;i<=100;i++)
        {
            if(a[i]>c)
            ans+=c;
            else ans+=a[i];
        }
        printf("%d\n",ans);
        
    }
    return 0;
}

B. Meeting on the Line

nn people live on the coordinate line, the ii-th one lives at the point xixi (1≤i≤n1≤i≤n). They want to choose a position x0x0 to meet. The ii-th person will spend |xi−x0||xi−x0| minutes to get to the meeting place. Also, the ii-th person needs titi minutes to get dressed, so in total he or she needs ti+|xi−x0|ti+|xi−x0| minutes.

Here |y||y| denotes the absolute value of yy.

These people ask you to find a position x0x0 that minimizes the time in which all nn people can gather at the meeting place.

Input

The first line contains a single integer tt (1≤t≤1031≤t≤103) — the number of test cases. Then the test cases follow.

Each test case consists of three lines.

The first line contains a single integer nn (1≤n≤1051≤n≤105) — the number of people.

The second line contains nn integers x1,x2,…,xnx1,x2,…,xn (0≤xi≤1080≤xi≤108) — the positions of the people.

The third line contains nn integers t1,t2,…,tnt1,t2,…,tn (0≤ti≤1080≤ti≤108), where titi is the time ii-th person needs to get dressed.

It is guaranteed that the sum of nn over all test cases does not exceed 2⋅1052⋅105.

Output

For each test case, print a single real number — the optimum position x0x0. It can be shown that the optimal position x0x0 is unique.

Your answer will be considered correct if its absolute or relative error does not exceed 10−610−6. Formally, let your answer be aa, the jury's answer be bb. Your answer will be considered correct if |a−b|max(1,|b|)≤10−6|a−b|max(1,|b|)≤10−6.

这题比C题难,题意是一个一维的坐标轴,然后给你n个人在轴上的位置x[i],然后给你这n个人需要穿衣服的时间t[i],让你找一个位置x0,每个人到这个位置需要的时间是t[i]+|x[i]-x0| ;

让你求一个最短的时间,在这个时间内所有人都能到达固定位置,输出这个最短时间对应的x0;

思路:首先分析一下,看一下数据可以判断可能是二分(确实是二分),然后二分最短时间,check函数判断这个时间内每个人能够到达的区间范围,如果所有人的到达区间都有交集,那么这个时间就是可以的;

注意,我们求的是一个区间范围,但是我们要输出这个点的位置,那么怎么求呢?

很简单,将左右区间加起来然后除以2就可以。

#include <bits/stdc++.h>
using namespace std;
const int N=100010;
double x[N];
double t[N];
int n;
double nowl,nowr;
bool check(double num)
{
    if(num<t[1])
    return false;
    nowl=max(x[1]-(num-t[1]),0.00000);
    //cout<<nowl<<endl;
    nowr=x[1]+(num-t[1]);
    //cout<<nowr<<endl;
    for(int i=2;i<=n;i++)
    {
        double ll=max(0.00000,x[i]-(num-t[i]));
        double rr=x[i]+(num-t[i]);
        if(nowl<=rr&&nowr>=rr)
        {
            nowr=min(rr,nowr);
            nowl=max(ll,nowl);
        }
        else if(ll>=nowl&&ll<=nowr)
        {
            nowr=min(rr,nowr);
            nowl=max(ll,nowl);
        }
        else return false;
        //cout<<nowl<<endl;
        //cout<<nowr<<endl;
    }
    return true;
}
double erfen()
{
    double l=0;
    double r=2e18;
    double k;
    while(r-l>1e-7)
    {
        double mid=(l+r)/2;
        if(check(mid)) k=(nowr+nowl)/2,r=mid;
        else l=mid;
    }
    return k;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%lf",&x[i]);
        for(int i=1;i<=n;i++) scanf("%lf",&t[i]);
        printf("%.6f\n",erfen());
    }
    return 0;
}

C. Minimum Notation

You have a string ss consisting of digits from 00 to 99 inclusive. You can perform the following operation any (possibly zero) number of times:

  • You can choose a position ii and delete a digit dd on the ii-th position. Then insert the digit min(d+1,9)min(d+1,9) on any position (at the beginning, at the end or in between any two adjacent digits).

What is the lexicographically smallest string you can get by performing these operations?

A string aa is lexicographically smaller than a string bb of the same length if and only if the following holds:

  • in the first position where aa and bb differ, the string aa has a smaller digit than the corresponding digit in bb.

Input

The first line contains a single integer tt (1≤t≤1041≤t≤104) — the number of test cases. Then the test cases follow.

Each test case consists of a single line that contains one string ss (1≤|s|≤2⋅1051≤|s|≤2⋅105) — the string consisting of digits. Please note that ss is just a string consisting of digits, so leading zeros are allowed.

It is guaranteed that the sum of lengths of ss over all test cases does not exceed 2⋅1052⋅105.

Output

Print a single string — the minimum string that is possible to obtain.

#include <bits/stdc++.h>
using namespace std;
vector<char> a;
string s;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        cin>>s;
        int n=s.size();
        char now=s[n-1];
        for(int i=n-1;i>=0;i--)
        {
            if(s[i]>now)
            {
                if(s[i]=='9')
                a.push_back(s[i]);
                else a.push_back(s[i]+1);
            }
            else
            {
                a.push_back(s[i]);
                now=s[i];
            }
        }
        sort(a.begin(),a.end());
        for(int i=0;i<n;i++)
        {
            printf("%c",a[i]);
        }
        printf("\n");
        a.clear();
    }
    return 0;
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值