您的位置:首页 > 其它

20170702练习赛比赛总结

2017-07-04 20:54 211 查看

A

思路&反思

发现人只有在接受到声音后才会进入咆哮,所以不可以通过二分一个时间后把每个人独立开算

仔细思考发现对于一个人一个人分析过来的他们只有一个最优的情况可以使时间最短,于是可以直接模拟

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=1e5+5;
bool mark[M];
int n,tot;
D k,ans,A[M],B[M],use;
int main(){
scanf("%lf%d",&k,&n);
for(int i=1;i<=n;i++)scanf("%lf",A+i);
sort(A+1,A+1+n);A[1]+=k;
/*我们用A[i]表示一个人可以受影响的最远距离*/
for(int i=1;i<n;i++){
A[i+1]-=use;
if(A[i]>=A[i+1]){
/*有可能一个人一直跑也跑不出前一个人可以影响的最远距离*/
if(A[i+1]+use<=A[i])A[i+1]+=use;
if(A[i+1]+use<=A[i])A[i+1]=A[i+1]+use+k;
else A[i+1]=A[i]+k;
continue;
}else{
D d=(A[i+1]-A[i])/2;
use+=d;
A[i+1]=A[i+1]-d+k;
}
}
printf("%.4f",use);
return 0;
}


小结

在情景感很强的题目中我们一定要仔细分析好题目的限制条件和各种情况后再来解答

同时我们也不要拘泥于一定要利用高端的算发来解决问题,可以寻找最优答案形成的过程来贪心

B

我们发现顺序是对问题的解没有影响的,于是问题就转化成区间的覆盖问题了

如果没有K这个限制条件,问题就很简单了。所以开始考虑K

/*
我们定义dp[i] 表示覆盖[1,i]区间的最小花费
于是我们有以下的转移方程
1.对于[1,i]的中的l且(A[i]-A[l]>k)
dp[i]=dp[l-1]+(A[i]-A[l]);
2.对于(A[i]-A[l-1]<=k)时更新
dp[i]=dp[l-1]+k;
*/
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int M=3e5+5;
int n,m,k,A[M],dp[M],l=1,mi=1e9;
int main(){
scanf("%d %d %d",&m,&k,&n);
For(i,1,n)scanf("%d",&A[i]);
sort(A+1,A+1+n);dp[1]=k;
For(i,2,n){
while(A[i]>=A[l]+k)mi=min(dp[l-1]-A[l]+1,mi),l++;
dp[i]=min(A[i]+mi,dp[l-1]+k);
}printf("%d",dp
);
return 0;
}


C

找规律之后最短路

#include<bits/stdc++.h>
#define For(i,a,b) for(int i=a;i<=b;++i)
#define pb(a) push_back(a)
#define sz(a) a.size()
using namespace std;
typedef long long ll;
const int M=6e5+5;
const ll INF=(ll)1e18;
int h[M],nxt[M],tot,t[M],num;
ll c[M],D[M],A[M][2],dis[M],n,m;
bool mark[M];
void Add(int x,int y,ll C){
c[++tot]=C,t[tot]=y,nxt[tot]=h[x],h[x]=tot;
c[++tot]=C,t[tot]=x,nxt[tot]=h[y],h[y]=tot;
}
ll to(ll x){
ll k=sqrt(x);
ll a=k*k,b=k*k-(4*k-4)+1;
if(k*k==x)return b;
if(x<a+(k+1))return b-a-2+x;
return b-a-4+x;
}
struct P{
int t;ll c;
bool operator<(const P&A)const {return c>A.c;}
};
ll SP(int S,int T){
priority_queue<P>Q;
for(int i=1;i<=num;i++)dis[i]=INF;
dis[S]=0;
Q.push((P){S,0});
while(!Q.empty()){
P to=Q.top();Q.pop();
int x=to.t;
if(x==T)return dis[x];
for(int i=h[x];i;i=nxt[i]){
int y=t[i];ll co=c[i];
if(dis[y]>dis[x]+co){
dis[y]=dis[x]+co;
Q.push((P){y,dis[y]});
}
}
}
}
int main(){
cin>>n>>m;
D[++num]=1;
for(int i=1;i<=m;i++){
scanf("%lld",&A[i][0]);
A[i][1]=to(A[i][0]);
D[++num]=A[i][0];
D[++num]=A[i][1];
}D[++num]=n;
sort(D+1,D+num+1);
num=unique(D+1,D+num+1)-D-1;
for(int i=1;i<=m;i++){
A[i][0]=lower_bound(D+1,D+1+num,A[i][0])-D;
A[i][1]=lower_bound(D+1,D+1+num,A[i][1])-D;
Add(A[i][0],A[i][1],1);
}
for(int i=1;i<num;i++)Add(i,i+1,D[i+1]-D[i]);
int S=lower_bound(D+1,D+1+num,1)-D;
int T=lower_bound(D+1,D+1+num,n)-D;
printf("%lld\n",SP(S,T));
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: