版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ShadowGhostH/article/details/80177976
题意:给出一个真分数的分子分母的和n,求满足条件的最大的真分数。真分数为:分子小于分母且分子分母互质。gcd判断。
#include<bits/stdc++.h>
using namespace std;
int gcd(int a, int b)
{
if(b==0) return a;
else return gcd(b, a%b);
}
int main()
{
int m, a, b;
cin>>m;
for(int i=1; i<=m/2; i++)
{
if(gcd(i, m-i)==1 && i!=m-i)
{
a = i;
b = m-i;
}
}
cout<<a<<" "<<b<<endl;
}
题意:给定n个房间,其中有m个房间有人,好房间的定义为:此房间没人,且是有人房间的隔壁。问好房间的最大和最小数量。
思路:我们可以知道一个有人的房间最多影响两个房间,那么当2*k>=n或3*k>=n时我们可知有人的房间可以将所有的房间都影响到,此时好房间就是n-k,其余时候好房间是2*k
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
int main()
{
int n, k, minn, maxx;
cin>>n>>k;
if(k==0 || k==n) minn = maxx = 0;
else {
minn = 1;
if(k*2>=n || 3*k>=n){
maxx=n-k;
}
else {
maxx=2*k;
}
}
cout<<minn<<" "<<maxx<<endl;
}
题意:给出n个飞机,假定第i号飞机原定于第i分钟起飞,每延迟1分钟会有一定的花费。现给出前k分钟是没有飞机起飞的,且1分钟只能安排一架飞机起飞,而且每个飞机不能比原定起飞时间更早。问怎么安排飞机起飞可以得到最小花费。
思路:把这到题抽象成了打牌,前k分钟没有飞机起飞,也就是说我们在第k分钟起,手里有了k张牌,然后每回合打出一张。此时我们为使得花费最少,需要将每分钟花费增长最大的那个先打出去。优先队列模拟
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 3e6+5;
struct Node{
int id;
int val;
int tim;
bool operator < (const Node &b) const{
return val<b.val;
}
}a[maxn];
priority_queue<Node> pq;
int main()
{
cin.sync_with_stdio(false);
int n, k;
cin>>n>>k;
for(int i=1; i<=n; i++)
{
cin>>a[i].val;
a[i].id = i;
}
for(int i=1; i<=k; i++)
pq.push(a[i]);
int p = k+1;
LL sum = 0;
while(!pq.empty())
{
if(p<=n) pq.push(a[p]);
Node now = pq.top();
pq.pop();
a[now.id].tim = p;
sum += (LL)a[now.id].val*(p-now.id);
p++;
}
printf("%I64d\n", sum);
for(int i=1; i<=n; i++)
printf("%d%c", a[i].tim, i==n?'\n':' ');
}
题意:有编号1~n的岛屿与0岛之间有航班,需要从n个岛选取代表去0号岛开一个为期k天的会议,到达和离开的当天不能开会,问如果能够在一起开会,输出最小花费,如果不能在一起开会输出-1
思路:和之前一个题目类似,我们将到达和离开分开考虑。用两个dp表示第i天所有人到达的最小花费和第i天所有人离去的最小花费,然后在枚举到达时间查找对应离开时间求解。
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 1e5+5;
const int maxm = 1e6+5;
const int INF = 0x3f3f3f3f;
//const LL INF = 0x3f3f3f3f3f3f3f3f;
int vis[maxn];
LL come[maxm], go[maxm];
struct Node{
int u, v;
int day;
LL cost;
bool operator < (const Node &b) const{
return day<b.day;
}
}a[maxn];
int main()
{
cin.sync_with_stdio(false);
memset(come, 0, sizeof come);
memset(go, 0, sizeof go);
// for(int i=0; i<=10; i++)
// printf("update %d: %lld\n", i, go[i]);
memset(vis, -1, sizeof vis);
int n, m, k, cnt, p;
cin>>n>>m>>k;
for(int i=0; i<m; i++)
cin>>a[i].day>>a[i].u>>a[i].v>>a[i].cost;
sort(a, a+m);
cnt = n;
LL best = 0;
for(int i=0; i<m; i++)
{
//printf("*** %d %d %d %lld\n", a[i].day, a[i].u, a[i].v, a[i].cost);
if(a[i].u == 0) continue;
if(vis[a[i].u] == -1){
cnt--;
vis[a[i].u] = a[i].cost;
best += a[i].cost;
}
else{
if(vis[a[i].u] > a[i].cost)
{
best = best + a[i].cost - vis[a[i].u];
vis[a[i].u] = a[i].cost;
}
}
if(!cnt) {
come[a[i].day] = best;
//cout<<"Come: "<<a[i].day<<" "<<best<<endl;
}
}
memset(vis, -1, sizeof vis);
cnt = n;
best = 0;
for(int i=m-1; i>=0; i--)
{
if(a[i].u!=0) continue;
if(vis[a[i].v] == -1){
cnt--;
vis[a[i].v] = a[i].cost;
best += a[i].cost;
}
else{
if(vis[a[i].v] > a[i].cost)
{
best = best + a[i].cost - vis[a[i].v];
vis[a[i].v] = a[i].cost;
}
}
if(!cnt) {
go[a[i].day] = best;
//cout<<"go: "<<a[i].day<<" "<<best<<endl;
}
}
best = -1;
for(int i=maxm-1; i>0; i--)
if(go[i] == 0 && go[i+1] != 0) {
go[i] = go[i+1];
//printf("update %d: %lld\n", i, go[i]);
}
k++;
for(int i=0; i+k<maxm; i++)
if(come[i]!=0 && go[i+k]!=0)
best = best==-1 ? come[i]+go[i+k] : min(best, come[i]+go[i+k]);
cout<<best<<endl;
}
E题不会,暂留坑