Codeforces Round#433 div 2

来源:互联网 发布:微销宝是什么软件 编辑:程序博客网 时间:2024/05/29 19:48

A.Fraction

Petya is a big fan of mathematics, especially its part related to fractions. Recently he learned that a fraction is called proper iff its numerator is smaller than its denominator (a < b) and that the fraction is called irreducible if its numerator and its denominator are coprime (they do not have positive common divisors except 1).

During his free time, Petya thinks about proper irreducible fractions and converts them to decimals using the calculator. One day he mistakenly pressed addition button ( + ) instead of division button (÷) and got sum of numerator and denominator that was equal to n instead of the expected decimal notation.

Petya wanted to restore the original fraction, but soon he realized that it might not be done uniquely. That’s why he decided to determine maximum possible proper irreducible fraction such that sum of its numerator and denominator equals n. Help Petya deal with this problem.

题意:给你一个数n,将其拆成两个数的和,并且这两个数互质,使a/b最大且且为真分数(a>b)

题解:n不大,可以直接暴力枚举,因为a/b要最大,故a,b尽量相邻

代码:

#include<bits/stdc++.h>using namespace std;int n;int gcd(int a,int b){    if (b == 0) return a;    return gcd(b,a%b);}int main(){    while (scanf("%d",&n)!=EOF)    {        if (n % 2)            printf("%d %d\n",n/2,n/2+1);        else        {            int k = n>>1;            for (int i=k-1;i>0;i--)                if (gcd(i,n-i) == 1)                {                    printf("%d %d\n",i,n-i);                    break;                }        }    }    return 0;}

B.Maxim Buys an Apartment

Maxim wants to buy an apartment in a new house at Line Avenue of Metropolis. The house has n apartments that are numbered from 1 to n and are arranged in a row. Two apartments are adjacent if their indices differ by 1. Some of the apartments can already be inhabited, others are available for sale.

Maxim often visits his neighbors, so apartment is good for him if it is available for sale and there is at least one already inhabited apartment adjacent to it. Maxim knows that there are exactly k already inhabited apartments, but he doesn’t know their indices yet.

Find out what could be the minimum possible and the maximum possible number of apartments that are good for Maxim.

题意:一排座位有n个,已知k个位置有人,但不知道具体位置。现在Maxim想要选择一个好位置,好位置的定义是,在该位置有相邻的人。问满足条件的位置最多有多少,最少有多少?

题解:k个人选n个位置,使可选位置最多即两个人中间相隔两个位置,如( * )(空)(空)( * )……使可选位置最少即所有人都往左或右选择,如( * )( * )(空)(空)

代码:

#include<bits/stdc++.h>using namespace std;int n,k,m,Max,Min;int main(){    scanf("%d %d",&n,&k);    m = (n-1)/3+1;    if (k >= m)//all spare house can choose        Max = n-k;    else        Max = 2*k;    if (n > k && k)        Min = 1;    else        Min = 0;    printf("%d %d\n",Min,Max);    return 0;}

C.Planning(贪心)

Helen works in Metropolis airport. She is responsible for creating a departure schedule. There are n flights that must depart today, the i-th of them is planned to depart at the i-th minute of the day.

Metropolis airport is the main transport hub of Metropolia, so it is difficult to keep the schedule intact. This is exactly the case today: because of technical issues, no flights were able to depart during the first k minutes of the day, so now the new departure schedule must be created.

All n scheduled flights must now depart at different minutes between (k + 1)-th and (k + n)-th, inclusive. However, it’s not mandatory for the flights to depart in the same order they were initially scheduled to do so — their order in the new schedule can be different. There is only one restriction: no flight is allowed to depart earlier than it was supposed to depart in the initial schedule.

Helen knows that each minute of delay of the i-th flight costs airport ci burles. Help her find the order for flights to depart in the new schedule that minimizes the total cost for the airport.

题意:有n架飞机要飞离,原定时间为(1-n),现需推迟k个单位时间,即时间为( k-(k+n) ),第i架飞机延迟1分钟,代价为ai,问如何分配起飞时间使得代价最小

题解:记价值为totv,则totv = ∑(b[i]-a[i]) * v[i] = ∑b[i] * v[i]-∑a[i] * v[i] (其中b[i]>=a[i]),因为∑a[i] * v[i]为定值,要使totv最小,则∑b[i] * v[i]最小。故,贪心策略为让v[i]大的先选择时间b[i] —— 离a[i]最近的大于a[i]的时间。

代码:

#include<bits/stdc++.h>using namespace std;const int maxn = 3e5+100;struct node{    int x,v;}a[maxn];set <int> s;int n,k,b[maxn];long long ans;bool cmp(node s,node t){    return s.v>t.v;}int main(){    scanf("%d %d",&n,&k);    for (int i=1;i<=n;i++)    {        scanf("%d",&a[i].v);        a[i].x = i;        s.insert(i+k);    }    sort(a+1,a+n+1,cmp);    set<int>::iterator it;    for (int i=1;i<=n;i++)    {        it = s.lower_bound(a[i].x);        b[a[i].x] = *it;        ans += (long long)(*it - a[i].x)*a[i].v;        s.erase(it);    }    printf("%I64d\n",ans);    for (int i=1;i<=n;i++) printf("%d ",b[i]);    return 0;}

D.Jury Meeting(贪心)

Country of Metropolia is holding Olympiad of Metrpolises soon. It mean that all jury members of the olympiad should meet together in Metropolis (the capital of the country) for the problem preparation process.

There are n + 1 cities consecutively numbered from 0 to n. City 0 is Metropolis that is the meeting point for all jury members. For each city from 1 to n there is exactly one jury member living there. Olympiad preparation is a long and demanding process that requires k days of work. For all of these k days each of the n jury members should be present in Metropolis to be able to work on problems.

You know the flight schedule in the country (jury members consider themselves important enough to only use flights for transportation). All flights in Metropolia are either going to Metropolis or out of Metropolis. There are no night flights in Metropolia, or in the other words, plane always takes off at the same day it arrives. On his arrival day and departure day jury member is not able to discuss the olympiad. All flights in Megapolia depart and arrive at the same day.

Gather everybody for k days in the capital is a hard objective, doing that while spending the minimum possible money is even harder. Nevertheless, your task is to arrange the cheapest way to bring all of the jury members to Metrpolis, so that they can work together for k days and then send them back to their home cities. Cost of the arrangement is defined as a total cost of tickets for all used flights. It is allowed for jury member to stay in Metropolis for more than k days.

题意:n+1座城市,1-n座城市的代表需要到0号城市一起工作k天,给出飞机的飞行日期,始发地,目的地,和价格,问是否n个人能一起工作k天,如果能,输出最小价格,否则输出-1

题解:
将飞机按飞行时间,始发地排序,我们可以得到让n个人都到0城市的最早时间,和n个人都能离开的最晚时间。那么这n个人一起工作的时间是在 EarlyTime 至 LastTime 中。
不断更新i城市去程和返程的最小花费,和去程或返程的最小总花费。
详见代码。

代码:

#include<bits/stdc++.h>using namespace std;const int maxn = 1e6+100;const long long MAX = 1e14;struct fly{    int d,f,t,v;    void read (int day,int from,int to,int cost)    {        d = day, f = from, t = to, v = cost;    }};fly a[maxn],b[maxn];int n,m,k,numa,numb,cnt,maxday,Time[2],st[2][maxn];long long u[2][maxn];//到达或回去的最小总花费bool g[maxn];bool cmpa(fly x,fly y){    return (x.d<y.d);}bool cmpb(fly x,fly y){    return (x.d>y.d);}void get_min(fly c[maxn],int num,int x){    cnt = 0;//how many people arrive    long long ans = 0;    memset(g,0,sizeof(g));    Time[x] = -1;    for (int i=1;i<=maxday;i++) u[x][i] = MAX;    for (int i=0;i<num;i++)    {        int city = max(c[i].f,c[i].t);        if (g[city] == 0)        {            st[x][city] = c[i].v;//st[x][i] i到达或返回的最小花费            ans += c[i].v;//sum of cost            ++cnt,g[city] = true;            if (cnt == n)            {                u[x][c[i].d] = ans;                Time[x] = c[i].d;            }        }        else        {            if (st[x][city] > c[i].v)            {                ans = ans - (st[x][city] - c[i].v);                st[x][city] = c[i].v;                if (cnt == n) u[x][c[i].d] = ans;                //x=0,u[0][j]在j时间之前全部到达的最小总花费。                //u=1,u[1][j]在j时间之后全部回去的最小总花费            }        }    }    return;}long long get_ans(){    long long ans = MAX;    for (int i=Time[0];i<Time[1]-k-1;i++)        u[0][i+1] = min(u[0][i],u[0][i+1]);    for (int i=Time[1];i>Time[0]+k+1;i--)        u[1][i-1] = min(u[1][i],u[1][i-1]);//更新u[x][i]    for (int i=Time[0];i+k+1<=Time[1];i++)        ans = min(ans,u[0][i]+u[1][i+k+1]);//计算往返总代价    return ans;}int main(){    scanf("%d %d %d",&n,&m,&k);    for (int i=0;i<m;i++)    {        int day,from,to,cost;        scanf("%d %d %d %d",&day,&from,&to,&cost);        maxday = max(maxday,day);        if (from)            a[numa++].read(day,from,to,cost);//去的飞机        else            b[numb++].read(day,from,to,cost);//回的飞机    }    sort(a,a+numa,cmpa);    sort(b,b+numb,cmpb);    get_min(a,numa,0);    get_min(b,numb,1);    if (Time[0]<0 || Time[1]<0 || Time[1]-Time[0]-1<k)        printf("-1\n");//如果无法全部到0城市,或无法全部回原来的城市,或者时间不到k天,则输出-1    else        printf("%I64d\n",get_ans());    return 0;}
原创粉丝点击