百度之星2020 初赛第二场

昨天是百度之星算法竞赛初赛的第二场,越做越崩溃,,,
今天早上早早起来补题
先上官方题解

在这里插入图片描述
在这里插入图片描述
其中应该是一二四题可做,第五题我以为是贪心或者决策优化,没想到题解给出的是网络流

真好啊 ,,,
大早上起来,HDU的评测机专为我开放
在这里插入图片描述

Poker

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 306 Accepted Submission(s): 128
Problem Description
小沃沃在玩一个有趣的游戏。
初始他有 n 块钱,每一轮他需要投入至少 m 块钱,系统会拿走其中 p% 的钱,并把剩下的钱还给他。
请问在最优情况下,小沃沃最多可以玩多少轮?
假设当前一轮小沃沃投入了 x 块钱,那么他可以收回 ⌊x×(1−p%)⌋ 块钱,其中 ⌊a⌋ 表示 a 取下整。
小沃沃每一轮投入的钱不能超过他现在拥有的钱。
每一轮投入的钱必须为整数。
Input
第一行一个正整数 test(1≤test≤100000) 表示数据组数。
对于每组数据,一行三个整数 n,m,p(1≤n≤100000,1≤m≤1000,1≤p≤100)。
Output
对每组数据输出一行一个整数表示答案
Sample Input
2
10 2 50
10 2 100
Sample Output
9
5
Source
2020 年百度之星·程序设计大赛 - 初赛二

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define  LL long long
#define Maxn 100005
using namespace std;
LL sum[Maxn];
int a[Maxn];
int main() {
    int m,p,n,T;  scanf("%d",&T);
    while(T--) {
        scanf("%d %d %d",&n,&m,&p);
        int cos = ceil(m * 1.0 * p *0.01);
        // 不写 m * 1.0 * p *0.01  不对
        if(m > n) {
            printf("0\n");
            continue;
        }
        n -= m;
        printf("%d\n",n / cos + 1);
    }
    return 0;
}

Distance

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 184 Accepted Submission(s): 69

Problem Description
小沃沃所在的世界是一个二维平面。他有 n 个朋友,第 i 个朋友距离他的距离为 a[i],小沃沃并不知道这些朋友具体在什么点上。

请问在最优情况下,小沃沃的朋友两两之间的欧几里得距离的和的最小值是几?

假设小沃沃的位置为 P0=(x0,y0),第 i 个朋友的位置为 Pi=(xi,yi),对于所有的 i,需要满足 dist(P0,Pi)=a[i],并且∑n−1i=1∑nj=i+1dist(Pi,Pj) 最小,其中 dist(X,Y) 为连接点 X 和点 Y 的线段的长度。xi,yi 都可以是任意实数。

Input
第一行一个正整数 test(1≤test≤10) 表示数据组数。

对于每组数据,第一行一个正整数 n(1≤n≤100000)。

接下来一行 n 个整数,第 i 个整数 ai 表示第 i 个朋友和小沃沃的距离。

Output
对每组数据输出一行一个数,表示 ∑n−1i=1∑nj=i+1dist(Pi,Pj) 的最小值。答案需要四舍五入到整数。

Sample Input
2
2
3 5
5
1 2 3 4 5
Sample Output
2
20

Source
2020 年百度之星·程序设计大赛 - 初赛二

题目分析
这个官方没有给出题解,但是经分析不难验证,总的两两之间距离之和最小的时候是所有的点成一条直线的时候,前缀和sum一下 最好是画图手推一下Ans 的计算公式

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define  LL long long
#define Maxn 100005
using namespace std;
LL sum[Maxn];
LL a[Maxn];
// 明明题目说ai小于等于10亿   但是ai不开long long 就是不对
int main() {
    int m,p,n,T;  scanf("%d",&T);
    ios::sync_with_stdio(false);
    while(T--) {
         scanf("%d",&n);
         for(int i=1; i<=n; i++) scanf("%lld",&a[i]);
         memset(sum,0,sizeof(sum));

         sort(a + 1 , a + n + 1);
         for(int i=1; i<=n; i++) sum[i] = (LL)(sum[i - 1] + a[i]);
         LL Ans = 0;

         for(int i=1; i<=n; i++)
             Ans += (LL)(sum[n] - sum[i - 1] - (LL)(a[i] * (n - i + 1)));

         printf("%lld\n",Ans);
    }
    return 0;
}

Covid

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 123 Accepted Submission(s): 43

Problem Description
科学家小沃沃在研究病毒传播的规律,从而控制疫情。

有 n 个人,编号分别为 1,2,…,n。我们用荧光粉代替病毒,编号为 1 的人,在第 0 时刻涂上了荧光粉,剩下的人在第 0 时刻没有涂。

对于第 i 个人,我们知道这个人在哪些时刻出现在了哪些地方。

如果时刻 t,某个人和身体上有荧光粉的人,出现在了同一地点,那么从时刻 t 以后,这个人也会沾上荧光粉。

从小到大输出实验结束后身体上有荧光粉的人的编号。

Input
第一行一个整数 T(1≤T≤20) 表示 T 组数据。

对于每组数据,第一行一个整数 n(1≤n≤20000) 表示 n 个人。

对于第 i 个人,第一行输入一个整数 leni 表示这个人的活动轨迹。

接下来 len[i] 行,每行输入两个整数 t,p(1≤t≤100,1≤p≤10) 表示这个人 t 时刻出现在了 p 位置,保证 t 按严格递增的顺序给出。

除了这 len[i] 个时刻,这个人都呆在家里,或者换句话说,他/她不在任何位置。
保证 len[1]+len[2]+…+len[n]≤200000。

Output
对于每组数据输出一行,表示所有患者的编号。按编号从小到大输出。

Sample Input
2
4
2
1 1
2 2
3
2 2
3 3
4 4
1
4 4
1
2 1
3
3
1 1
3 1
6 1
3
4 1
5 1
6 1
1
5 1

Sample Output
1 2 3
1 2

样例解释
Case 1:
第 2 时刻,位置 2,1 与 2 相遇,2 沾上了。
第 4 时刻,位置 4,2 与 3 相遇,3 沾上了。

//排个序 模拟
// 官方题解什么用个小根堆维护一个二元组啥的.emmmmmm
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;
const int Maxn = 2e5 + 5;
struct Node{ int id,t,p; }a[Maxn];
int vis[Maxn],len;

inline bool cmp(Node A,Node B) {
    if(A.t != B.t) return A.t < B.t;// 时间绝对第一关键字
    else if(A.p != B.p) return A.p < B.p;
    else return A.id < B.id;
}

int main(int argc,char* argv[]) {
    int n,T; scanf("%d",&T);
    while(T--) {
        int tot = 0;
        scanf("%d",&n);
        memset(vis,0,sizeof(vis));// 感染
        for(int j=1; j<=n; j++) {
            scanf("%d",&len);
            for(int i=1; i<=len; i++) {
            	a[++tot].id = j;
                scanf("%d %d",&a[tot].t,&a[tot].p);
                // id 表示 是第几个人的活动轨迹
            }
        }
        vis[1] = 1;
        sort(a + 1,a + tot + 1,cmp);
        for(int i=2; i<=tot; i++) {
            if(a[i].t == a[i - 1].t && a[i].p == a[i - 1].p) {// 同时同地
                if(vis[a[i].id] == 1 || vis[a[i - 1].id] == 1) {
                    vis[a[i].id] = vis[a[i - 1].id] = 1;
                    for(int j=i; (a[j].p ==a[j - 1].p && a[j].t == a[j - 1].t) &&j>=1; j--)
                        vis[a[j].id] = vis[a[j -1].id] = 1;

                }
            }
        }
        int flag = 0;
        for(int i=1; i<=n; i++) {
        	if(vis[i]) {
        		if(flag) printf(" %d",i);
        		else { flag = 1; printf("%d",i); }
			}
		}

        printf("\n");
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35776409/article/details/107588599
今日推荐