三道水题,但还有水人。
40/100/100
3810. 【USACO2014 3月】Watering the Fields (Standard IO)
Time Limits: 1000 ms Memory Limits: 262144 KB Detailed Limits
Goto ProblemSet最小生成树板题,至于为什么没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 }
3811. 【USACO2014 3月】The Lazy Cow (Standard IO)
Time Limits: 2000 ms Memory Limits: 262144 KB Detailed Limits
Goto ProblemSet简单的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度,变成正方形再做。
3812. 【USACO2014 3月】Mooo Moo (Standard IO)
Time Limits: 1000 ms Memory Limits: 262144 KB Detailed Limits
Goto ProblemSetdp水题。
先搞出每个草场牛的数量,用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 }