zoukankan      html  css  js  c++  java
  • 牛客网国庆集训派对Day6 题目 2018年

    链接:https://www.nowcoder.com/acm/contest/206/A
    来源:牛客网

    Birthday

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 1048576K,其他语言2097152K
    64bit IO Format: %lld

    题目描述

    恬恬的生日临近了。宇扬给她准备了一个蛋糕。
    正如往常一样,宇扬在蛋糕上插了n支蜡烛,并把蛋糕分为m个区域。因为某种原因,他必须把第i根蜡烛插在第ai个区域或第bi个区域。区域之间是不相交的。宇扬在一个区域内同时摆放x支蜡烛就要花费x2的时间。宇扬布置蛋糕所用的总时间是他在每个区域花的时间的和。
    宇扬想快些见到恬恬,你能告诉他布置蛋糕最少需要多少时间吗?

    输入描述:

    第一行包含两个整数n,m(1 ≤ n ≤ 50, 2≤ m≤ 50)。
    接下来n行,每行两个整数a
    i
    ,b
    i
    (1 ≤ a
    i
    , b
    i
     ≤ m)。

    输出描述:

    一个整数表示答案。
    示例1

    输入

    复制
    3 3
    1 2
    1 2
    1 2

    输出

    复制
    5
    示例2

    输入

    复制
    3 3
    1 2
    2 3
    1 3

    输出

    复制
    3
    思路:最小费用最大流。
    代码:
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <vector>
     4 #include <queue>
     5   
     6 using namespace std;
     7   
     8 const int INF = 0x3f3f3f3f;
     9 const int MAXN = 5005;
    10   
    11 struct Edge{
    12     int value,flow,to,rev;
    13     Edge(){}
    14     Edge(int a,int b,int c,int d):to(a),value(b),flow(c),rev(d){}
    15 };
    16   
    17 vector<Edge> E[MAXN];
    18   
    19 inline void Add(int from,int to,int flow,int value){
    20     E[from].push_back(Edge(to,value,flow,E[to].size()));
    21     E[to].push_back(Edge(from,-value,0,E[from].size()-1));
    22 }
    23   
    24 bool book[MAXN];//用于SPFA中标记是否在queue中
    25 int cost[MAXN];//存费用的最短路径
    26 int pre[MAXN];//存前节点
    27 int pree[MAXN];//存在前节点的vector中的下标
    28   
    29 bool Spfa(int from,int to){
    30     memset(book,false,sizeof book);
    31     memset(cost,INF,sizeof cost);
    32     book[from] = true;
    33     cost[from] = 0;
    34     queue<int> Q;
    35     Q.push(from);
    36     while(!Q.empty()){
    37         int t = Q.front();
    38         book[t] = false;
    39         Q.pop();
    40         for(int i=0 ; i<E[t].size() ; ++i){
    41             Edge& e = E[t][i];
    42             if(e.flow > 0 && cost[e.to] > cost[t] + e.value){
    43                 cost[e.to] = cost[t] + e.value;
    44                 pre[e.to] = t;
    45                 pree[e.to] = i;
    46                 if(book[e.to] == false){
    47                     Q.push(e.to);
    48                     book[e.to] = true;
    49                 }
    50             }
    51         }
    52     }
    53     return cost[to] != INF;
    54 }
    55   
    56 int Work(int from,int to){
    57     int sum = 0;
    58     while(Spfa(from,to)){
    59         int mflow = INF;//SPFA找到的最短路径的最小容量
    60         int flag = to;
    61         while(flag != from){
    62             mflow = min(mflow,E[pre[flag]][pree[flag]].flow);
    63             flag = pre[flag];
    64         }
    65         flag = to;
    66         while(flag != from){
    67             sum += E[pre[flag]][pree[flag]].value * mflow;
    68             E[pre[flag]][pree[flag]].flow -= mflow;
    69             E[flag][E[pre[flag]][pree[flag]].rev].flow += mflow;
    70             flag = pre[flag];
    71         }
    72     }
    73     return sum;
    74 }
    75   
    76 int main(){
    77      
    78     int N,M;
    79     while(scanf("%d %d",&N,&M) == 2){
    80         int a,b;
    81         for(int i=1 ; i<=N ; ++i){
    82             scanf("%d %d",&a,&b);
    83             Add(i,a+N,1,0);
    84             Add(i,b+N,1,0);
    85             Add(0,i,1,0);
    86         }
    87         for(int i=1 ; i<=M ; ++i){
    88             for(int j=1 ; j<=99 ; j+=2){//99 = 2*50-1;
    89                 Add(i+N,M+N+1,1,j);
    90             }
    91         }
    92         printf("%d
    ",Work(0,M+N+1));
    93         for(int i=0 ; i<=M+N+1 ; ++i)E[i].clear();
    94     }
    95      
    96     return 0;
    97 }

    链接:https://www.nowcoder.com/acm/contest/206/B
    来源:牛客网

    Board

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 1048576K,其他语言2097152K
    64bit IO Format: %lld

    题目描述

    恬恬有一个nx n的数组。她在用这个数组玩游戏:
    开始时,数组中每一个元素都是0。
    恬恬会做某些操作。在一次操作中,她可以将某一行的所有元素同时加上一个值,也可以将某一列的所有元素同时加上一个值。
    在几次操作后,一个元素被隐藏了。你能帮助她回忆隐藏的数是几吗?

    输入描述:

    第一行一个整数n(1≤ n≤ 1000)。
    接下来n行每行n个整数表示数组a。
    第(i+1)行的第j个元素表示a
    ij
    (a
    ij
    =-1或0≤ a
    ij
     ≤ 10000)。-1表示隐藏的元素。

    输出

    仅一个整数表示答案。
    示例1

    输入

    复制
    3
    1 2 1
    0 -1 0
    0 1 0

    输出

    复制
    1

    思路:先把每一行先减去每一行的最小值,然后找到“-1”所在的行和列(行和列的各自的最小值的和即为所求)
    代码:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int inf=1e9+5;
     4 int a[1010][1010];
     5 int main()
     6 {
     7     int n;
     8     int x,y;
     9     scanf("%d",&n);
    10     for(int i=1; i<=n; i++)
    11     {
    12         for(int j=1; j<=n; j++)
    13         {
    14             scanf("%d",&a[i][j]);
    15             if(a[i][j]==-1)
    16             {
    17                 x=i,y=j;
    18             }
    19  
    20         }
    21     }
    22     int sum;
    23     for(int i=1; i<=n; i++)
    24         {
    25             sum==inf;
    26             if(i==x)
    27                 continue;
    28             for(int j=1;j<=n;j++)
    29             {
    30                 sum=min(sum,a[i][j]);
    31             }
    32             for(int j=1;j<=n;j++)
    33             {
    34                 a[i][j]-=sum;
    35             }
    36         }
    37     for(int i=1; i<=n; i++)
    38         {
    39             sum==inf;
    40             if(i==y)
    41                 continue;
    42             for(int j=1;j<=n;j++)
    43             {
    44                 sum=min(sum,a[j][i]);
    45             }
    46             for(int j=1;j<=n;j++)
    47             {
    48                 a[j][i]-=sum;
    49             }
    50         }
    51         int tmp1=inf,tmp2=inf;
    52         for(int i=1;i<=n;i++)
    53         {
    54             if(i==x)
    55             {
    56                 continue;
    57             }
    58             tmp1=min(tmp1,a[i][y]);
    59         }
    60         for(int i=1;i<=n;i++)
    61         {
    62             if(i==y)
    63             {
    64                 continue;
    65             }
    66             tmp2=min(tmp2,a[x][i]);
    67         }
    68         printf("%d
    ",tmp1+tmp2);
    69     return 0;
    70 }
    链接:https://www.nowcoder.com/acm/contest/206/C
    来源:牛客网

    Circle

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 1048576K,其他语言2097152K
    64bit IO Format: %lld

    题目描述

    现在我们要把这n个数字首尾连接组成一个环,使得相邻元素互质的对数尽可能多。请输出最大对数。

    输入描述:

    一行一个整数n(1≤ n≤ 1000)。

    输出描述:

    一行一个整数表示答案。
    示例1

    输入

    复制
    4

    输出

    复制
    4

    说明

    样例的一种构造方法为1 4 3 2。
    思路:输入n,输出n,此时的排序方式为1,n,n-1,n-2,n-3,,,,,5,4,3,2
    代码:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3  
     4 int main()
     5 {
     6     int n;
     7     scanf("%d",&n);
     8     printf("%d
    ",n);
     9     return 0;
    10 }
    链接:https://www.nowcoder.com/acm/contest/206/H
    来源:牛客网

    Mountain

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 1048576K,其他语言2097152K
    64bit IO Format: %lld

    题目描述

    平面上有n座山,每座山都有左右两面,第i座山的高度为ai,现在弱弱在第一座山的左边山脚下(高度为0),他想要依此爬过这些山,到达第n座山的右边山脚下。
    除了简单的爬上爬下,还有一种特殊操作。
    如果弱弱目前在第i座山右面的海拔x的位置,且第j ( i < j )座山的海拔大于等于x,且第座山中没有一座山的海拔高于x,那么他可以使用绳索滑到第j座山左面海拔x的位置。
    弱弱想找到一种方式,使得他在行程中海拔变化的幅度最小。请输出最小幅度。

    输入描述:

    第一行一个整数n(1≤ n≤ 1000)。
    接下来一行n个整数a
    i
    (1≤ a
    i
    ≤ 1000)表示每座山的高度。

    输出描述:

    一行一个整数表示答案。
    示例1

    输入

    复制
    5
    1 3 5 4 2

    输出

    复制
    10
    思路:最高点的两倍。
    代码:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int a[1010];
     4 int main()
     5 {
     6     int n;
     7     scanf("%d",&n);
     8     for(int i=0;i<n;i++)
     9     {
    10         scanf("%d",&a[i]);
    11     }
    12     sort(a,a+n);
    13     printf("%d
    ",2*a[n-1]);
    14     return 0;
    15 }
    链接:https://www.nowcoder.com/acm/contest/206/E
    来源:牛客网

    Growth

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 1048576K,其他语言2097152K
    64bit IO Format: %lld

    题目描述

    弱弱有两个属性a和b,这两个属性初始的时候均为0,每一天他可以通过努力,让a涨1点或b涨1点。
    为了激励弱弱努力学习,我们共有n种奖励,第i种奖励有xi,yi,zi三种属性,若a≥ xi且b≥ yi,则弱弱在接下来的每一天都可以得到zi的分数。
    问m天以后弱弱最多能得到多少分数。

    输入描述:

    第一行一个两个整数n和m(1≤ n≤ 1000,1≤ m≤ 2000000000)。
    接下来n行,每行三个整数x
    i
    ,y
    i
    ,z
    i
    (1≤ x
    i
    ,y
    i
    ≤ 1000000000,1≤ z
    i
     ≤ 1000000)。

    输出描述:

    一行一个整数表示答案。
    示例1

    输入

    复制
    2 4
    2 1 10
    1 2 20

    输出

    复制
    50

    备注:

    在样例中,弱弱可以这样规划:第一天a涨1,第二天b涨1,第三天b涨1,第四天a涨1。
    共获得0+0+20+30=50分。

    思路:离散+DP
    代码:
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef long long ll;
     5 const int maxn = 1e3 + 100;
     6 
     7 map<pair<int, int>, int> p;
     8 set<int> sx, sy;
     9 int x[maxn], y[maxn];
    10 ll dp[maxn][maxn], v[maxn][maxn];
    11 
    12 int main()
    13 {
    14    int n, m;
    15    int cnt1 = 1, cnt2 = 1;
    16    scanf("%d %d", &n, &m);
    17    for(int i = 0; i < n; i++) {
    18        int tx, ty, tz;
    19        scanf("%d %d %d", &tx, &ty, &tz);
    20        p[pair<int, int>(tx, ty)] += tz;
    21        if(!sx.count(tx)) sx.insert(tx), x[cnt1++] = tx;
    22        if(!sy.count(ty)) sy.insert(ty), y[cnt2++] = ty;
    23    }
    24 
    25    sort(x + 1, x + cnt1);
    26    sort(y + 1, y + cnt2);
    27 
    28    for(int i = 1; i < cnt1; i++) {
    29      for(int j = 1; j < cnt2; j++) {
    30         if(!p[pair<int, int>(x[i], y[j])]) v[i][j] = v[i - 1][j] + v[i][j - 1] - v[i - 1][j - 1];
    31         else v[i][j] = v[i - 1][j] + v[i][j - 1] - v[i - 1][j - 1] + p[pair<int, int>(x[i], y[j])];
    32      }
    33    }
    34 
    35    for(int i = 0; i < cnt1; i++) {
    36       for(int j = 0; j < cnt2; j++) {
    37         dp[i + 1][j] = max(dp[i + 1][j], dp[i][j] + (x[i + 1] - x[i] - 1) * v[i][j] + v[i + 1][j]);
    38         dp[i][j + 1] = max(dp[i][j + 1], dp[i][j] + (y[j + 1] - y[j] - 1) * v[i][j] + v[i][j + 1]);
    39       }
    40    }
    41 
    42    ll ans = 0;
    43    for(int i = 1; i < cnt1; i++) {
    44     for(int j = 1; j < cnt2; j++) {
    45         ll t = dp[i][j] + (m - x[i] - y[j]) * v[i][j];
    46         ans = max(ans, t);
    47     }
    48    }
    49    printf("%lld
    ", ans);
    50 }

    参考博客:https://blog.csdn.net/deerly_/article/details/81584521



     
     
  • 相关阅读:
    UOJ #455 [UER #8]雪灾与外卖 (贪心、模拟费用流)
    Codeforces 482E ELCA (LCT)
    Codeforces 798D Mike and distribution (构造)
    AtCoder AGC017C Snuke and Spells
    HDU 6089 Rikka with Terrorist (线段树)
    HDU 6136 Death Podracing (堆)
    AtCoder AGC032D Rotation Sort (DP)
    jenkins+python+kubectl实现批量更新k8s镜像
    Linux 下载最新kubectl版本的命令:
    jenkins X 和k8s CI/CD
  • 原文地址:https://www.cnblogs.com/weixq351/p/9749026.html
Copyright © 2011-2022 走看看