现在的位置: 首页 > 综合 > 正文

Codeforces Round #134 (Div. 2)

2018年01月14日 ⁄ 综合 ⁄ 共 2075字 ⁄ 字号 评论关闭

第一题:

题意:给一个折线,其中任意偶数i (2 ≤ i ≤ 2n)满足yi比相邻两点都高,有人对于其中K个峰点都提高了1个单位,给你修改后的图,请输出原来可能的图,任意一种即可。

题解:找偶数i (2 ≤ i ≤ 2n)满足yi比相邻两点都高1以上,把前K个满足的点减1就是原图

代码:

#include<cstdio>
#include<cstring>
using namespace std;
int num[250];
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=0;i<2*n+1;++i)
        scanf("%d",num+i);
    for(int i=1;i<2*n;++i)
        if(k&&num[i]-num[i-1]>1&&num[i]-num[i+1]>1)
        {
            k--;
            num[i]--;
        }
    for(int i=0;i<2*n+1;++i)
        if(i==0) printf("%d",num[i]);
        else     printf(" %d",num[i]);
    puts("");
    return 0;
}

第二题:

题意:模拟飞机售票点,当一个人买票时,票价等于飞机剩下的空座位数,坐哪架由顾客选择。现有N个人和M架飞机,告诉你M架飞机初始空座位数,问这N个人买票的最大值和最小值

题解:这题属于贪心加模拟,求最小值的时候对于每个顾客肯定是从空座位最小的飞机那买,求最大值的时候对于每个顾客从空座位最多的飞机那买。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<functional>
using namespace std;
int num[1005];
int mult(int x,int t)
{
    return ((x+x-t+1)*t)/2;
}
int main()
{
    int n,m;
    int minn,maxx,summ;
    minn=maxx=0;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;++i)
        scanf("%d",num+i);
    if(n==1)
    {
        minn=mult(num[0],n);
        printf("%d %d\n",minn,minn);
        return 0;
    }
    sort(num+1,num+m+1);
    summ=n;
    for(int i=1;i<=m;++i)
    {
        if(num[i]<=summ)
        {
            minn+=mult(num[i],num[i]);
            summ-=num[i];
        }
        else
        {
            minn+=mult(num[i],summ);
            break;
        }
    }
    summ=n;
    sort(num+1,num+m+1,greater<int>());
    for(;num[1]!=0;)
    {
        if(summ>num[1]-num[2])
        {
            int k=(num[1]==num[2]?1:num[1]-num[2]);
            maxx+=mult(num[1],k);
            summ-=(k);
            num[1]-=k;
        }
        else
        {
            maxx+=mult(num[1],summ);
            break;
        }
        sort(num+1,num+m+1,greater<int>());
    }
    printf("%d %d\n",maxx,minn);
    return 0;
}

第三题:

题意:对于每个点,他可以从该点向四周出发任意长度的直线到另外的点,现给你N个点的坐标,问还需添加几个点满足他可以从任意点出发经过任意长度的路径到其他任意一点。

题解:当两点的横坐标或者纵坐标相同时代码它们相互可达,而对于任意不可达的两点添加一个点即可满足互达条件,这题可以用并查集来做,求出有几个集合,需要添加的点数就是集合数减一。

代码:

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct point
{
    int x,y;
    bool flag;
} num[105];
int main()
{
    int n,a,b;
    queue<int> q;
    scanf("%d",&n);
    for(int i=1; i<=n; ++i)
    {
        scanf("%d%d",&num[i].x,&num[i].y);
        num[i].flag=false;
    }
    int summ=-1;
    for(int i=1; i<=n; ++i)
    {
        if(num[i].flag==false)
        {
            num[i].flag=true;
            summ++;
            q.push(i);
            for(; !q.empty();)
            {
                int k=q.front();
                q.pop();
                for(int j=1; j<=n; ++j)
                {
                    if(j!=k&&num[j].flag==false)
                    {
                        if(num[k].x==num[j].x||num[k].y==num[j].y)
                        {
                            num[j].flag=true;
                            q.push(j);
                        }
                    }
                }
            }
        }
    }
    if(summ==-1)  summ=0;
    printf("%d\n",summ);
    return 0;
}

第四题:

第五题:


来源:http://blog.csdn.net/ACM_Ted

抱歉!评论已关闭.