9.8训练日志

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.
拆一个数成两个互质数(也可以是1)

#include<bits/stdc++.h>
using namespace std;
int main()
{int m,i,x;
cin>>m;
for(i=m/2;i>=1;i--)
 {if(__gcd(i,m-i)==1)
   {cout<<i<<" "<<m-i;
   return 0;
   }
 }
}

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.
买公寓,如果周围两旁至少有一个邻居则好,给出公寓数量及有人的数量,求最多几个是好的.
分析后输出公寓数量减去有人的数量以及有人的数量乘上2中小的那个即可.

#include<bits/stdc++.h>
using namespace std;
int main()
{int n,k;
cin>>n>>k;
if(k==n||k==0)
{cout<<0<<" "<<0;
return 0;
}
else cout<<1<<" "<<min(n-k,k*2);
}

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.
稍有难度,飞机场延误,每个飞机都延误k分钟,每个飞机有各自应起飞时间,以及延误一分钟所需补的钱,每分钟只可起飞一架飞机,求最小补钱数.
贪心,在每分钟都选择如果不飞要补钱最多的飞机起飞.不过正常数组去写会tle,要用优先队列写(在某大佬指点下刚刚学会的)

#include<bits/stdc++.h>
using namespace std;
struct cmp {
    int x,y;
    friend bool operator <(cmp f, cmp g) {
        return f.x < g.x;//daµÄÓÅÏȼ¶¸ß
    }
} a[300005];
int c[300005];
int main() {
    int n,k,i;long long int ans=0;
    priority_queue<cmp>b;
    cmp p;
    cin>>n>>k;
    for(i=1; i<=n; i++) {
        cin>>a[i].x;
        a[i].y=i;
    }
    for(i=1; i<=k; i++)
        b.push(a[i]);
    for(i=k+1; i<=n; i++) {
        b.push(a[i]);
        p=b.top();
        c[p.y]=i;
        b.pop();
        if(p.y<i)
        ans+=(long long int)(i-p.y)*p.x;
    }
    for(i=n+1; i<=n+k; i++) {
        p=b.top();
        c[p.y]=i;
        b.pop();
        ans+=(long long int)(i-p.y)*p.x;;
    }
    cout<<ans<<endl;
    for(i=1; i<=n; i++)
        printf("%d ",c[i]);
}

总结:

还是要多学学优先队列之类的算法啊..

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值