17.10.02
Posted *ZJ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了17.10.02相关的知识,希望对你有一定的参考价值。
- 上午
- 入门OJ
- 入门OJ 2043: [Noip模拟题]小Y的炮
继续昨晚上的绝望……
实在不行了,学习了一个网上的AC代码,用map实现的,总算是AC了
代码:
#include<map> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long using namespace std; struct cannon{ ll a,d; bool operator <(const cannon &b)const{ return (a<b.a || (a==b.a && d<b.d)); } }c[250005]; ll mountain[250005],last,k; map<ll,ll>f; int n,m,ans,cnt; int main(){ freopen("in.in","r",stdin); freopen("mine.out","w",stdout); scanf("%d%d%lld",&n,&m,&k); for(int i=1;i<=n;i++) scanf("%lld",&mountain[i]); for(int i=1;i<=m;i++) scanf("%lld%lld",&c[i].a,&c[i].d); sort(c+1,c+m+1); for(int i=1;i<=m;i++){ while(cnt&&c[cnt].d<=c[i].d) cnt--; c[++cnt]=c[i]; } last=0;f[0]=0; for(int i=1;i<=cnt;i++){ if(i!=1) last=c[i-1].a; //p[i].d>p[i+1].d for(ll j=max(last,c[i].a-c[i].d)+1;j<=c[i].a;j++){ ll t=(j-last-1)/c[i].d+1; f[j]=f[max(0ll,j-(c[i].d*t))]+t; } } last=0; int p=0; for(int i=n;i>=1;i--){ while(p<=cnt&&c[p].a<mountain[i]) p++; if(p>cnt)break; if(p!=1)last=c[p-1].a; ll t=(mountain[i]-last-1)/c[p].d+1; ll q=f[max(0ll,mountain[i]-(c[p].d*t))]+t; if(k>=q)k-=q,++ans;else break; } printf("%d %lld\n",ans,k); return 0; }
- 入门OJ 2044: [Noip模拟题]tree
由于边都为正权,即一个节点往上走,累积的边权和只会越来越大。
所以对于每个节点,向上最多只会存在一个祖先到它的边权和为k
那么只需dfs遍历时维护到该点的路径,并二分查找是否存在一个祖先到它的距离为k。
代码:
#include<cstdio> #include<cstring> #include<iostream> #define MAXN 200005 using namespace std; struct edge{ int to,val,next; }e[MAXN*2]; int head[MAXN],sum[MAXN]; int n,rt,k,cnt,ans,ent=1; void add(int u,int v,int w){ e[ent]=(edge){v,w,head[u]}; head[u]=ent++; } void binary_search(){ int tmp=sum[cnt]-k; int sub=lower_bound(sum+1,sum+cnt+1,tmp)-sum; if(sum[sub]==tmp) ans++; } void dfs(int u,int w,int fa){ cnt++; sum[cnt]=sum[cnt-1]+w; binary_search(); for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(v==fa) continue; dfs(v,e[i].val,u); } cnt--; } int main(){ scanf("%d%d%d",&n,&rt,&k); for(int i=1,a,b,c;i<n;i++){ scanf("%d%d%d",&a,&b,&c); add(a,b,c); add(b,a,c); } dfs(rt,0,0); printf("%d",ans); return 0; }
- 入门OJ 2047: [Noip模拟题]博览购票
水水题,就如题目下面说的那样:队列入门
代码:
#include<queue> #include<cstdio> #include<cstring> #include<iostream> using namespace std; queue<int>q; int cnt[2005]; int n,m,ans=0x3f3f3f3f,g,a,b; int main(){ scanf("%d%d",&n,&m); for(int i=1,x;i<=n;i++){ scanf("%d",&x); if(!cnt[x]) g++; q.push(x); cnt[x]++; while(cnt[q.front()]>1) cnt[q.front()]--,q.pop(); if(g==m&&q.size()<ans){ ans=q.size(); a=i-q.size()+1; b=i; } } printf("%d %d",a,b); return 0; }
以上是关于17.10.02的主要内容,如果未能解决你的问题,请参考以下文章