Codeforces Round #501

Codeforces Round #501

Problem A.Points in Segments
题目概述
给定Ox轴总长度N和线段个数M,并分别给出M个线段所在的区间[l,r]覆盖在Ox轴上,问在轴上还有几个点没有被覆盖并将其罗列出来。数据规模N,M均小于100.

思路:
一个类似于桶排序的思想,用bool数组去做覆盖,模拟这个过程,最后统计并输出即可。

代码A:

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
int i,j,n,m,b[1001];
int r()
{
    int ans=0;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        ans*=10;
        ans+=ch-'0';
        ch=getchar();
    }
    return ans;
}
int x,y;
int main()
{
    n=r(),m=r();
    for(i=1;i<=n;i++)
    {
        x=r(),y=r();
        for(j=x;j<=y;j++)
        b[j]=1;
    }
    int sum=0;
    for(i=1;i<=m;i++)
    if(!b[i])
    sum++;
    cout<<sum<<endl;
    for(i=1;i<=m;i++)
    if(!b[i])
    cout<<i<<" ";
    return 0;
}

Problem B.Obtaining the String
题目概述
给定两个长度为N(N<=50)的小写字母组成的字符串S,T,可以将S字符串中相邻的ai与ai+1两位互换,求一种可行的互换方式,使得S变为T,若不能则输出-1,若能则输出互换的步数和题干中所描述的“ai与ai+1两位互换”的i。要求总步数不超过10000.

思路:
贪心思想。直接从前往后搜,若Si=Ti则继续向后搜,反之则从S中找到使得Sj=Ti的j,并将Sj转移到Si的位置上,转移时想着记录操作。由于数据规模不大,时间复杂度为ON2,所以可行。

代码B:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
using namespace std;
int i,j,n,m;
int c[10001];
char a[51],b[51];
int r()
{
    int ans=0;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        ans*=10;
        ans+=ch-'0';
        ch=getchar();
    }
    return ans;
}

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

    int j=1,swi=0;
    char x;
    while(j<=n)
    {
        for(i=j;i<=n;i++)
        if(a[i]==b[j])
        {
            for(int k=i;k>j;k--)
            {
                x=a[k];
                a[k]=a[k-1];
                a[k-1]=x; 
                c[++m]=k-1;
            }
            swi=1;
            break;
        }
        if(!swi)
        {
            cout<<-1;
            return 0;
        }
        j++;swi=0;
    }
    cout<<m<<endl;
    for(i=1;i<=m;i++)
    cout<<c[i]<<" ";
    return 0;
}

Problem C.Songs Compression
题目概述
给定N个音乐的原大小和压缩后的大小,现在有一个容量为M的闪存器,需要我们选取几个音乐进行压缩,使得这N个音乐完全被容纳在闪存器中。题目要求压缩的音乐数量尽可能的小,输出最小的个数。

思路:
个人认为比B题简单的贪心,实际上就是把我们现在欠下的容量用压缩掉的体积补回来,所以思路就是对每一个音乐作差,然后排序,让压缩体积大的尽可能的先压缩,之后模拟这个压缩过程直至满足题意,输出个数,如果全部压缩之后仍然不行,则输出-1。

代码C:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
long long i,j,n,m;
struct data
{
    long long x,y,w;
}a[100001];
long long r()
{
    long long ans=0;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        ans*=10;
        ans+=ch-'0';
        ch=getchar();
    }
    return ans;
}

long long cmp(data aa,data bb)
{
    if(aa.w>bb.w) return 1;
    return 0;
}
long long sum,sum1;
int main()
{
    n=r(),m=r();
    for(i=1;i<=n;i++)
    {
        a[i].x=r(),a[i].y=r();
        a[i].w=a[i].x-a[i].y;
        sum+=a[i].y;
        sum1+=a[i].x;
    }
    if(sum>m)
    {cout<<-1;
    return 0;}
    sum1-=m;
    if(sum1<=0)
    {cout<<0;
    return 0;}
    long long tot=0;
    sort(a+1,a+n+1,cmp);
    for(i=1;i<=n;i++)
    {
        sum1-=a[i].w;
        tot++;
        if(sum1<=0)
        {cout<<tot;return 0;} 
    }

}
/*
4 14
5 5
4 4
3 3
3 2
*/

猜你喜欢

转载自blog.csdn.net/Stockholm_Sun/article/details/81413550