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



     
     
  • 相关阅读:
    JS日期格式转换
    VMware虚拟化集群的配置(一)
    网络初级篇之STP(概念原理)
    运维学习篇之jenkins的安装(CentOS7)
    网络初级篇之配置telnet登录网络设备(实验)
    Linux操作篇之OpenKM的安装(汉化)
    网络初级篇之网络设备的FTP(原理与实验)
    网络初级篇之直连路由与静态路由(原理与实验)
    网络初级篇之DHCP原理与配置(原理与实验)
    网络初级篇之OSPF(二)实验
  • 原文地址:https://www.cnblogs.com/weixq351/p/9749026.html
Copyright © 2011-2022 走看看