UESTC 2016 Summer Training #6 Div.2(未完待续)

来源:互联网 发布:mac万能钥匙怎么连接 编辑:程序博客网 时间:2024/06/05 00:32

题目来源:
UVALive 6434-6443

A
题意:给你N个数,让你把这些数分成M堆,每堆有一个值定义为该堆中最大值与最小值之差,问你所有这些值之和最小为多少。
做法:很显然,先对所有数排个序,然后计算排序后数组中相邻值之差为多少这个(N个数,所以有N-1个差),再对这个差值排序,由于分成M堆,故肯定有M-1个空隙,因此你只需要在N-1个差中选择最大的M-1个
最后答案已经很明显,详见代码。

#include <bits/stdc++.h>#define _ ios_base::sync_with_stdio(0);cin.tie(0);#define INF 0x3f3f3f3f#define eps 1e-6typedef long long LL;const double pi = acos(-1.0);const long long mod = 1e9 + 7;using namespace std;int a[105];int b[105];int main(){    int T,M,N;    cin >> T;    int cas = 1;    while(T--)    {        cin >> N >> M;        for(int i = 0;i < N;i++)            cin >> a[i];        sort(a,a + N);        int sum = a[N - 1] - a[0];        for(int i = 1;i < N;i++)            b[i] = a[i] - a[i - 1];        sort(b + 1,b + N);        for(int i = N - 1;i > N - M;i--)            sum -= b[i];        printf("Case #%d: ",cas++);        printf("%d\n",sum);    }    return 0;}

D

题意:N个点,M条边,在N个点里给了你K个重要的点,让你把所有非重要点至少连到一个重要点上,问你边权和最小是多少
分析:很明显的,这题就是求一个最小生成树,用kruskal算法解决。
这题特殊的地方只有一个,你需要把所有重要点之间连上边,边权为0,这样你就会增加了N*(N-1)/2条边,加上原来的M条,你对所有这些边排序
然后对这N个点,N*(N-1)/2+M条边跑一个最小生成树就行了。

#include <bits/stdc++.h>#define INF 0x3f3f3f3f#define eps 1e-6typedef long long LL;const double pi = acos(-1.0);const long long mod = 1e9 + 9;using namespace std;int u[100005],v[100005],r[100005];LL w[100005];int k[100005],p[100005];int cmp(const int i,const int j){    return w[i] < w[j];}int Find(int x){    return p[x] == x ? x : p[x] = Find(p[x]);}int main(){    int T,M,N,K;    cin >> T;    int cas = 1;    while(T--)    {        cin >> N >> M >> K;        for(int i = 0;i < K;i++)            cin >> k[i];        int U,V;        LL W;        for(int i = 0;i < M;i++)        {            cin >> U >> V;            scanf("%lld",&W);            u[i] = U - 1;            v[i] = V - 1;            w[i] = W;        }        for(int i = 0;i < K;i++)            for(int j = i + 1; j < K;j++)            {                u[M] = k[i] - 1;                v[M] = k[j] - 1;                w[M++] = 0;            }        LL ans = 0;        for(int i = 0;i < N;i++)            p[i] = i;        for(int i = 0;i < M;i++)            r[i] = i;        sort(r,r + M,cmp);        for(int i = 0;i < M;i++)        {            int e = r[i];            int x = Find(u[e]);            int y = Find(v[e]);            if(x != y)            {                ans += w[e];                p[x] = y;            }        }        printf("Case #%d: ",cas++);        printf("%lld\n",ans);    }    return 0;}

G
题意:让你模拟一家医院接收病人的情况,在一些时刻会有病人进来,一些时刻你需要接收一个最需要救助的病人。让你输出每次医院可以接收病人时,最需要救助的病人。
做法:根据r值对病人进行分类,由于r只有100,于是开一个STL优先队列。
每次有病人进来时把他的st值换算成0点值放入对应的r的优先队列中,每次需要接收病人时,就从所有这些优先队列中取出值最大的病人进行救助。进行模拟即可。
注意:每次开始之前记得清空每个优先队列。

#include <bits/stdc++.h>#define INF 0x3f3f3f3f#define eps 1e-6typedef long long LL;const double pi = acos(-1.0);const long long mod = 1e9 + 9;using namespace std;priority_queue <int> q[105];char s[10];int main(){    int T,M,N,K;    cin >> T;    int cas = 1;    int t0,st0,r,t;    while(T--)    {        for(int i = 0;i <= 100;i++)        {            while(!q[i].empty())                q[i].pop();        }        cin >> N;        printf("Case #%d:\n",cas++);        while(N--)        {            scanf("%s",s);            if(s[0] == 'A')            {                scanf("%d",&t);                int pos;                int MAXV = -INF;                for(int i = 0;i <= 100;i++)                {                    if(!q[i].empty())                    {                        if(MAXV <= q[i].top() + (t * i))                        {                            MAXV = q[i].top() + (t * i);                            pos = i;                        }                    }                }                q[pos].pop();                printf("%d %d\n",MAXV,pos);            }            else            {                scanf("%d %d %d",&t0,&st0,&r);                st0 -= t0 * r;                q[r].push(st0);            }        }    }    return 0;}

I
题意:让你把M个数用最小的花费挪成间距相等的排列。
分析:首先不妨假设最后的位置为0,N/M,2N/M,……
然后对应算出最大和最小挪动的次数,最后答案显然就是两者之差的平均值向上取整。

#include <bits/stdc++.h>#define INF 0x3f3f3f3f#define eps 1e-6typedef long long LL;const double pi = acos(-1.0);const long long mod = 1e9 + 9;using namespace std;int a[1000005];int main(){    int T,M,N,K;    cin >> T;    int cas = 1;    while(T--)    {        cin >> N >> M;        for(int i = 1;i <= M;i++)            scanf("%d",&a[i]);        sort(a + 1,a + M + 1);        int MAX = -INF,MIN = INF;        for(int i = 1,t = 0;i <= M;i++,t += N / M)        {            MAX = max(MAX,a[i] - t);            MIN = min(MIN,a[i] - t);        }        printf("Case #%d: ",cas++);        printf("%d\n",(MAX - MIN + 1) / 2);    }    return 0;}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 鼻炎的部位总有痰怎么办 真丝衣服有褶子怎么办 百褶裙褶皱没了怎么办 AE模版素材丢失怎么办 pr 显示素材丢失怎么办 儿童上课小动作多怎么办 小孩锁骨骨裂怎么办 小孩子不爱写作业怎么办 小孩不交作业怎么办 小孩子不喜欢写作业怎么办 实行两票制 一品红会怎么办 跳舞之后浑身疼怎么办 事业编体检怀孕怎么办 辞职后报到证怎么办 学生早上起床困怎么办 延期毕业报到证怎么办 学校报到证丢失怎么办 生育险不满一年怎么办 产假结束上班宝宝怎么办 辞职后生育津贴怎么办 员工要不到工资怎么办 试用期不发工资怎么办 单位不给探亲假怎么办 工作5.5天周六怎么办 不爱运动的幼儿怎么办 总跟孩子生气怎么办 小孩经常感冒发烧怎么办 家里出现皮球虫怎么办 第一天教幼儿园怎么办 幼师遇到家长投诉怎么办 小孩喜欢玩手机怎么办 幼师掐孩子胳膊怎么办 孩子喜欢抓人怎么办 小孩顽皮不听教怎么办 出现了心理异常怎么办 想问下心理出问题该怎么办 大班幼儿爱说话怎么办 孩子不喜欢去幼儿园怎么办 别人抢宝宝玩具怎么办 新生儿抱淘气了怎么办 野兔子吃葵花怎么办