三道水题,但还有水人。
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 ProblemSet
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 }