• 【纪中受难记】——C2Day4:水题大赏


    三道水题,但还有水人。

    40/100/100


    Description

    由于缺少雨水,FJ 想要建造一个在他的N(1 N 2000)块田之间送水的灌溉系统。
    每块田地i 由一个二维平面上独一无二的点(xi; yi) 描述,这里有0 <= xi; yi <=1000。在两块田地i 和j 之间建造水管的费用等于它们之间欧几里得距离的平方:(xi-xj)^2+(yi-yj)^2
    FJ 希望建造一个连接所有田地并且花费最小的管道系统——满足从任意田地出发,水可以通过一系列管道到达另外的任意一块田地。
    不幸的是,帮助FJ 安装灌溉系统的承包商拒绝安装任何花费(欧几里得长度平方)小于C(1 C 1; 000; 000)的管道。
    请帮助FJ 计算他最少需要为连接他所有田地的管道网络支付多少钱。
     
     

    Input

    第一行:整数N 和C。
    第2 至N + 1 行:第i 行包含整数xi 和yi。

    Output

    输出单独一行一个整数——连接所有田地的管道网络的最小费用,或者当满足条件的网络不可能建造时输出-1。
     

    Sample Input

    3 11
    0 2
    5 0
    4 3

    Sample Output

    46
    样例解释:
    有三块田地,分别在坐标(0; 2); (5; 0) 和(4; 3)。承包商将只会安装费用不少于11 的管道。
    FJ 不能建造连接分别在(4; 3) 和(5; 0) 的田地的管道,因为它的费用只有10。
    故他只得建造连接(0; 2) 和(5; 0) 且费用为29 的管道,以及连接(0; 2) 和(4; 3)且费用为17 的管道。
     
     

    Data Constraint

    对于20% 的数据,有N <= 10。
    对于30% 的数据,有N <= 100。
    对于40% 的数据,有N <= 200。

    最小生成树板题,至于为什么没AC,因为数组开小了。。。

    给出两种写法,稠密图所以最好用prim。

    Kruskal:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int read(){
     4     int x=0,f=1;
     5     char c=getchar();
     6     while(!isdigit(c)){
     7         if(c=='-') f=-1;
     8         c=getchar();
     9     }
    10     while(isdigit(c)){
    11         x=(x<<1)+(x<<3)+(c^48);
    12         c=getchar();
    13     }
    14     return x*f;
    15 }
    16 typedef long long ll;
    17 const int N=201000;
    18 int n,c,cnt;
    19 int x[N],y[N],fa[N];
    20 ll ans;
    21 struct node{
    22     int x,y,len;
    23 }e[N<<4];
    24 bool cmp(node t1,node t2){
    25     return t1.len<t2.len;
    26 }
    27 int findf(int x){
    28     return fa[x]==x?x:fa[x]=findf(fa[x]);
    29 }
    30 int main(){
    31     n=read();c=read();
    32     for(int i=1;i<=n;i++){
    33         x[i]=read();y[i]=read();
    34         fa[i]=i;
    35     }
    36     for(int i=1;i<=n;i++){
    37         for(int j=i+1;j<=n;j++){
    38             ll len=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
    39             if(len<c) continue;
    40             e[++cnt]=(node){i,j,len};
    41         }
    42     }
    43     sort(e+1,e+cnt+1,cmp);
    44     for(int i=1;i<=cnt;i++){
    45         if(findf(e[i].x)!=findf(e[i].y)){
    46             ans+=e[i].len;
    47             fa[findf(e[i].x)]=e[i].y;
    48         }
    49     }
    50     int t=findf(1);
    51     for(int i=2;i<=n;i++){
    52         if(findf(i)!=t){
    53             printf("-1");
    54             return 0;
    55         }
    56     }
    57     printf("%lld",ans);
    58     return 0;
    59 }

    Prim:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int read(){
     4     int x=0,f=1;
     5     char c=getchar();
     6     while(!isdigit(c)){
     7         if(c=='-') f=-1;
     8         c=getchar();
     9     }
    10     while(isdigit(c)){
    11         x=(x<<1)+(x<<3)+(c^48);
    12         c=getchar();
    13     }
    14     return x*f;
    15 }
    16 typedef long long ll;
    17 const int M=2010;
    18 const ll inf=1e16;
    19 int n,c,cnt,tot,now=1;
    20 int x[M],y[M],vis[M],head[M*M];
    21 ll dis[M];
    22 struct edge{
    23     int to,next;
    24     ll w;
    25 }e[M*M];
    26 void addedge(int from,int to,ll w){
    27     e[++cnt]=(edge){to,head[from],w};
    28     head[from]=cnt;
    29 }
    30 ll ans;
    31 void prim(){
    32     for(int i=2;i<=n;i++) dis[i]=inf;
    33     for(int i=head[1];i;i=e[i].next){
    34         ll w=e[i].w;
    35         int v=e[i].to;
    36         dis[v]=min(w,dis[v]);
    37     }
    38     
    39     while(++tot<n){
    40         bool flag=1;
    41         ll minn=inf;
    42         vis[now]=1;
    43         for(int i=1;i<=n;i++){
    44             if(!vis[i]&&minn>dis[i]){
    45                 minn=dis[i];
    46                 now=i;
    47                 flag=0;
    48             }
    49         }
    50         ans+=minn;
    51         for(int i=head[now];i;i=e[i].next){
    52             int v=e[i].to;ll w=e[i].w;
    53             if(!vis[v]&&dis[v]>w){
    54                 dis[v]=w;
    55             }
    56         }
    57         if(flag){
    58             printf("-1");
    59             exit(0);
    60         }
    61     }
    62     
    63 }
    64 int main(){
    65     n=read();c=read();
    66     for(int i=1;i<=n;i++){
    67         x[i]=read();y[i]=read();
    68     }
    69     for(int i=1;i<=n;i++){
    70         for(int j=i+1;j<=n;j++){
    71             ll len=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
    72             if(len<c) continue;
    73             addedge(i,j,len);
    74             addedge(j,i,len);
    75         }
    76     }
    77     prim();
    78     printf("%lld",ans);
    79     return 0;
    80 }

    Description

    夏天很热,贝茜越发地懒散了。她想要使自己位于她的田里一个尽可能在短距离内够到美味的青草的位置。
    贝茜居住的田野被描述为一个N 乘N 方格组成的棋盘(1 <= N <= 400)。
    在第r 行第c 列的格子(1 <= r; c <= N)包含G(r; c)(0 <= G(r; c) <= 1000)单位的青草(节操)。从她在棋盘内的初始方格出发,贝茜只愿意走K 步路(0 <= K <= 2* N)。每一步路她从当前的位置向正北,正南,正东或正西移动一格。
    举个例子,假如棋盘如下,这里(B) 描述贝茜的初始位置(在第三行第三列):

    50 5 25* 6 17
    14 3* 2* 7* 21
    99* 10* 1*(B) 2* 80*
    8 7* 5* 23* 11
    10 0 78* 1 9
    如果K = 2,那么贝茜只能到达有星号(*)标记的位置。
    请帮助贝茜确定,当她选择在棋盘中的最佳初始位置时,她能够到的最大青草总量。
     
     

    Input

    第一行:整数N 和K。
    第2 至N + 1 行:第r + 1 行包含N 个整数用以描述棋盘的第r 行。

    Output

    输出单独一行一个整数——如果她在最佳初始位置(从这个位置她能够到最多的青草),那么贝茜能够到青草的最大总量。
     

    Sample Input

    5 2
    50 5 25 6 17
    14 3 2 7 21
    99 10 1 2 80
    8 7 5 23 11
    10 0 78 1 9

    Sample Output

    342
    样例解释:
    在上面的例子里,贝茜如果位于棋盘的正中央,那么她能够到总共为342 单位的青草。
     

    Data Constraint

    对于20% 的数据,N<=20
    对于30% 的数据,N<= 50;K<=10
    对于40% 的数据,N <=100;K <= 20

    简单的n^3写法:用前缀和维护即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 inline int read(){
     4     int x=0,f=1;
     5     char c=getchar();
     6     while(!isdigit(c)){
     7         if(c=='-') f=-1;
     8         c=getchar();
     9     }
    10     while(isdigit(c)){
    11         x=(x<<1)+(x<<3)+(c^48);
    12         c=getchar();
    13     }
    14     return x*f;
    15 }
    16 const int N=410;
    17 int n,k;
    18 long long ans;
    19 int a[N][N],s[N][N];
    20 long long sum[N][N];
    21 int main(){
    22     n=read();k=read();
    23     for(register int i=1;i<=n;i++){
    24         for(register int j=1;j<=n;j++){
    25             a[i][j]=read();
    26             s[i][j]=s[i][j-1]+a[i][j];
    27         }
    28     }
    29     for(register int i=1;i<=n;i++){
    30         for(register int j=1;j<=n;j++){
    31             for(register int t=max(1,i-k);t<=min(n,i+k);t++){
    32                 int l=max(1,j-(k-abs(i-t)));
    33                 int r=min(n,j+(k-abs(t-i)));
    34                 sum[i][j]+=s[t][r]-s[t][l-1];
    35             }
    36             ans=max(ans,sum[i][j]);
    37         }
    38     }
    39     printf("%lld",ans);
    40     return 0;
    41 }

    正解好像可以将菱形转45度,变成正方形再做。


    Description

    FJ 已经完全忘记了他有多少头奶牛!但是,跑到他的草场里数奶牛是一件很尴尬的事情,因为他不想让奶牛们知道他记忆有问题。作为替代,他决定秘密地把麦克风种在奶牛们通常聚集的草场里,然后只要从他听到的哞哞声音量中确定奶牛的数目即可。
    FJ 的N 块草场(1 <= N <= 100)沿着一条笔直的路排成了一排。每块草场里可能有若干种不同的奶牛;FJ 的奶牛总共有B 种不同的种类(1 <= B <= 20),并且种类i 的一头奶牛叫起来的音量为V (i)(1 <= V (i) <= 100)。再者,沿着道路有一股强悍的风在吹,将哞哞叫的声音从路的左边传到右边:如果在某草场哞哞叫声音量为X,那么在下一个草场里会听到上边X -1 音量的叫声(并且在再下一个草场是X -2,等等)。更正式地说,一个草场的哞哞叫总音量为这个草场里奶牛哞哞的音量之和,加上X -1,这里X 是上一个草场的哞哞叫总音量。
    给定FJ 从每个草场里记录的哞哞音量,请帮助他计算出他所拥有的奶牛的可能的最少数量。
    任何一个草地上记录的音量值不超过100,000
     

    Input

    第一行:整数N 和B。
    第2 至B + 1 行:第i + 1 行包含整数V (i)。
    第B + 2 至B + N + 1 行:第B + i + 1 行包含第i 个草场哞哞叫的总音量。

    Output

    输出单独一行一个整数——FJ 最少拥有多少头奶牛;或者如果没有一种奶牛分配方案满足输入的限制,那么输出-1。
     

    Sample Input

    5 2
    5
    7
    0
    17
    16
    20
    19

    Sample Output

    4
    样例解释:
    FJ 有5 块草场,哞哞音量分别为0; 17; 16; 20; 19。有两种奶牛,第一种哞哞的音量为5,另外一种音量为7.
    在第二块草场,有两头种类#1 的奶牛和一头种类#2 的奶牛,并且在第4 块草场有另外一头种类#1 的奶牛。
     
     

    Data Constraint

    对于20% 的数据,N <= 20。
    对于30% 的数据,N <= 30;B <= 5。
    题目测试数据有梯度。

    dp水题。

    先搞出每个草场牛的数量,用dp[i]表示叫声为i最少可以有多少头牛。

    dp[i]=min(dp[i],dp[i-v[j]]+1)

    直接输出答案即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int read(){
     4     int x=0,f=1;
     5     char cc=getchar();
     6     while(!isdigit(cc)){
     7         if(cc=='-') f=-1;
     8         cc=getchar();
     9     }
    10     while(isdigit(cc)){
    11         x=(x<<1)+(x<<3)+(cc^48);
    12         cc=getchar();
    13     }
    14     return x*f;
    15 }
    16 const int N=110;
    17 int n,b,cnt;
    18 int v[N],a[N];
    19 int c[N];
    20 long long f[100010];
    21 long long ans;
    22 bool cmp(int t1,int t2){
    23     return t1>t2;
    24 }
    25 int main(){
    26     n=read();b=read();
    27     for(int i=1;i<=b;i++) v[i]=read();
    28     sort(v+1,v+b+1,cmp);
    29     for(int i=1;i<=n;i++) a[i]=read();
    30     for(int i=n;i>=2;i--){
    31         if(a[i-1]==0) continue;
    32         a[i]-=a[i-1]-1;
    33     }
    34     cnt=0;
    35     for(int i=1;i<=n;i++){
    36         if(!a[i]) continue;
    37         c[++cnt]=a[i];
    38     }
    39     memset(f,0x3f,sizeof(f));
    40     f[0]=0;
    41     for(int i=1;i<=b;i++){
    42         for(int j=v[i];j<=100000;j++){
    43             f[j]=min(f[j],f[j-v[i]]+1);
    44         }
    45     }
    46     for(int i=1;i<=cnt;i++){
    47         ans+=f[c[i]];
    48     }
    49     printf("%lld",ans);
    50     return 0;
    51 }
    ——抓住了时间,却不会利用的人,终究也逃不过失败的命运。
  • 相关阅读:
    SpringBoot RequestBody ajax提交对象
    微信小程序常用样式汇总
    微信小程序常用控件汇总
    java多线程实现多客户端socket通信
    客户端连接Codis集群
    crontab 解析
    在 RHEL/CentOS 7 上配置NTP时间服务器
    tomcat的bin目录中startup.bat/tomcat.6.exe/tomcat6w.exe区别
    Windows 下tomcat安装及将多个tomcat注册为Windows服务
    Oracle 数据库排错之 ORA-00600
  • 原文地址:https://www.cnblogs.com/Nelson992770019/p/11636129.html
Copyright © 2020-2023  润新知