J题,也可能是别人读完题在给我说的原因吧,思维就跟着他的思路走,然后赛后才发现去除中间一段之后找最大的平均值,只需要留一段,或者是从第一个向后找,或者是最后一个向前找,取最大的平均值就可以,代码:
#include<bits/stdc++.h> using namespace std; #define LL long long int p[1000005]; int main() { int n; cin>>n; for(int i=1;i<=n;i++) { cin>>p[i]; } double ans=0,re=0,sm=0; for(int i=1;i<=n;i++) { sm=sm+p[i]; re=sm/i; if(re>ans)ans=re; } re=0; sm=0; for(int i=n;i>0;i--) { sm=sm+p[i]; re=sm/(n-i+1); if(re>ans)ans=re; } printf("%.10lf\n",ans); }
I题,当时J被卡了就没看,之后第一次看的时候,感觉不难,然后wa了两次之后察觉事情没那么简单,一开始以为把大于k的路不存,然后dfs找满足的路再取最小值就行,但是不对,一个队友指出错误,就是,在某一个点,可以先到修车点在回来,这样就不能确定在某一个位置是否要走到修车点,要用两遍最短路,第一遍先不去修车点,找一次,第二次在加上修车点,n不大可以用floyed,代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; int tire[505]; ll dis[505][505]; ll a[505][505]; const ll inf=0x3f; int main() { int n,m,t,u,v; int i,j,k; ll d,w; memset(dis,inf,sizeof(dis)); memset(a,inf,sizeof(a)); scanf("%d%d%d%lld",&n,&m,&t,&d); for(i=1; i<=t; i++) { scanf("%d",&tire[i]); } tire[0]=1; tire[t+1]=n; for(i=1; i<=m; i++) { scanf("%d%d%lld",&u,&v,&w); dis[u][v]=min(dis[u][v],w); dis[v][u]=dis[u][v]; } for(k=1; k<=n; k++) { for(i=1; i<=n; i++) { for(j=1; j<=n; j++) { dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]); } } } for(i=0; i<=t+1; i++) { for(j=0; j<=t+1; j++) { if(dis[tire[i]][tire[j]]>d) { a[tire[i]][tire[j]]=-1; a[tire[j]][tire[i]]=-1; } else { a[tire[i]][tire[j]]=dis[tire[i]][tire[j]]; a[tire[j]][tire[i]]=a[tire[i]][tire[j]]; } } } for(k=0; k<=t+1; k++) { for(i=0; i<=t+1; i++) { for(j=0; j<=t+1; j++) { if(a[tire[i]][tire[k]]==-1||a[tire[k]][tire[j]]==-1) { continue; } else { if(a[tire[i]][tire[j]]==-1)a[tire[i]][tire[j]]=a[tire[i]][tire[k]] +a[tire[k]][tire[j]]; else a[tire[i]][tire[j]] = min(a[tire[i]][tire[j]], a[tire[i]][tire[k]] +a[tire[k]][tire[j]]); } } } } if(a[1][n]==-1||a[1][n]==0x3f3f3f3f3f3f3f3f) printf("stuck\n"); else printf("%lld\n",a[1][n]); }