2016百度之星 补题记
Posted youmi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2016百度之星 补题记相关的知识,希望对你有一定的参考价值。
1003 拍照
思路:先把所有的线段在x轴上可观察到的位置求出来,起点和终点对应数组a里的x,y,排序后从坐标最小开始枚举。如果遇到起点标志,就加一(说明从这个位置开始可以看见);结束点标志减一(说明从这个位置开始不可见)。还有一个值得注意的是:只有向左行驶的船只可见坐标大于向右行驶的船只,才可能在某个时刻同时出现在照片里
/************************************************************** Problem:hdu 5417 User: youmi Language: C++ Result: Accepted Time:1591MS Memory:1816K ****************************************************************/ //#pragma comment(linker, "/STACK:1024000000,1024000000") //#include<bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <stack> #include <set> #include <sstream> #include <cmath> #include <queue> #include <deque> #include <string> #include <vector> #define zeros(a) memset(a,0,sizeof(a)) #define ones(a) memset(a,-1,sizeof(a)) #define sc(a) scanf("%d",&a) #define sc2(a,b) scanf("%d%d",&a,&b) #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scs(a) scanf("%s",a) #define sclld(a) scanf("%I64d",&a) #define pt(a) printf("%d\\n",a) #define ptlld(a) printf("%I64d\\n",a) #define rep(i,from,to) for(int i=from;i<=to;i++) #define irep(i,to,from) for(int i=to;i>=from;i--) #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define lson (step<<1) #define rson (lson+1) #define eps 1e-6 #define oo 0x3fffffff #define TEST cout<<"*************************"<<endl const double pi=4*atan(1.0); using namespace std; typedef long long ll; inline int read() { int x=0,f=1; char ch=getchar(); while (ch<\'0\'||ch>\'9\') {if (ch==\'-\') f=-1; ch=getchar();} while (ch>=\'0\'&&ch<=\'9\') {x=x*10+ch-\'0\'; ch=getchar();} return x*f; } const int maxn=20000+10; int n,cnt,x,y,z,d,po,lmax,l,r,ans; struct data { int x,y,z; }a[maxn]; bool cmp(data a,data b) { if (a.x!=b.x) return a.x<b.x; else { if (a.y!=b.y) return a.y<b.y; else return a.z<b.z; } } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif int T_T; scanf("%d",&T_T); for(int kase=1;kase<=T_T;kase++) { n=read(); cnt=0; for (int i=1;i<=n;i++) { x=read(),y=read(),z=read(),d=read(); if (y-x<=2*z) { if (d==1) po=0; else po=1; a[++cnt].x=y-z; a[cnt].y=0; a[cnt].z=po; a[++cnt].x=x+z; a[cnt].y=1; a[cnt].z=po; } } sort(a+1,a+cnt+1,cmp); lmax=l=r=ans=0; for (int i=1;i<=cnt;i++) { if (a[i].z==0) { if (a[i].y==0) ++l; else --l; } else { if (a[i].y==0) ++r; else --r; } if (l>lmax) lmax=l; if (lmax+r>ans) ans=lmax+r; } printf("Case #%d:\\n%d\\n",kase,ans); } return 0; }
2016"百度之星" - 初赛(Astar Round2B)
思路:先选出[l,r]区间内的最小值,然后枚举[l,r]内的所以值,就可以算出以a[p]为最小值的所有区间的【区间的价值】了;不过有一点需要注意:在以a[p]为 最小值时,计算出的【区间大小大于等于3】(假设区间大小为k)的【区间的价值】,应该是区间大小为[2,k]内的最大值。
/************************************************************** Problem:hdu 5696 User: youmi Language: C++ Result: Accepted Time:1419MS Memory:4484K ****************************************************************/ //#pragma comment(linker, "/STACK:1024000000,1024000000") //#include<bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <stack> #include <set> #include <sstream> #include <cmath> #include <queue> #include <deque> #include <string> #include <vector> #define zeros(a) memset(a,0,sizeof(a)) #define ones(a) memset(a,-1,sizeof(a)) #define sc(a) scanf("%d",&a) #define sc2(a,b) scanf("%d%d",&a,&b) #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scs(a) scanf("%s",a) #define sclld(a) scanf("%I64d",&a) #define pt(a) printf("%d\\n",a) #define ptlld(a) printf("%I64d\\n",a) #define rep(i,from,to) for(int i=from;i<=to;i++) #define irep(i,to,from) for(int i=to;i>=from;i--) #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define lson (step<<1) #define rson (lson+1) #define eps 1e-6 #define oo 0x3fffffff #define TEST cout<<"*************************"<<endl const double pi=4*atan(1.0); using namespace std; typedef long long ll; template <class T> inline void read(T &n) { char c; int flag = 1; for (c = getchar(); !(c >= \'0\' && c <= \'9\' || c == \'-\'); c = getchar()); if (c == \'-\') flag = -1, n = 0; else n = c - \'0\'; for (c = getchar(); c >= \'0\' && c <= \'9\'; c = getchar()) n = n * 10 + c - \'0\'; n *= flag; } int Pow(int base, ll n, int mo) { if (n == 0) return 1; if (n == 1) return base % mo; int tmp = Pow(base, n >> 1, mo); tmp = (ll)tmp * tmp % mo; if (n & 1) tmp = (ll)tmp * base % mo; return tmp; } //*************************** int n; const int maxn=200000+10; int a[maxn]; ll ans[maxn]; ll temp[maxn]; void sovle(int l,int r) { if(r<l) return ; int p=0; int len=(r-l+1); rep(i,0,len) temp[i]=0; rep(i,l,r) { if(a[i]<a[p]) p=i; } rep(i,l,p) temp[p-l+1]=Max(temp[p-l+1],1ll*a[p]*a[i]); rep(i,p,r) temp[r-p+1]=Max(temp[r-p+1],1ll*a[p]*a[i]); rep(i,3,len) temp[i]=Max(temp[i],temp[i-1]); rep(i,1,len) ans[i]=Max(ans[i],temp[i]); sovle(l,p-1); sovle(p+1,r); } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif while(~sc(n)) { a[0]=oo; rep(i,1,n) sc(a[i]); zeros(ans); sovle(1,n); rep(i,1,n) ptlld(ans[i]); } }
思路:C(n-2,n+m-4);
思路:对区间起末坐标存入数组排序,然后枚举,遇到起点存入队列,遇到末点更新答案。下面是具体做法:
用y数组记录下各个区间的id,l,r;并用x数组记录下区间的id,区间起(末)坐标并标记为起(末);对x数组进行排序,然后一一枚举x数组并将标记为起始点的坐标压入队列,这里的队列用数组实现。当然这个过程我们需要两个数组:index用来标记队列中点对应的区间id,pt用来标记区间id对应队列中的位置。如果为起始点,那么我们直接压入队列就好了。如果为末点,我们就得处理他。
处理操作:
- 首先,如果队列元素个数小于k,直接把队列中id对应的位置弹出去就好了,我们这里是标记为-1;
- 如果个数大于等于k,我们就更新答案。因为我们已经对x排序过,所以先进队列的起始坐标值肯定更小;而我们只需要k个区间交就可以了,所以我们取队列中的第k个值来计算。这里第k个值所对应队列中的位置我们用flag记录。
- 如果当前处理的id在队列中的位置在flag前面,那么flag指向的是k-1个区间交的位置,所以我们要不断向后寻找。因为被弹出队列的位置都被标记为-1,所以while循环到非-1就是当前的k个区间交对应的位置。
/************************************************************** Problem:hdu 5700 User: youmi Language: C++ Result: Accepted Time:1996MS Memory:7208K ****************************************************************/ //#pragma comment(linker, "/STACK:1024000000,1024000000") //#include<bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <stack> #include <set> #include <sstream> #include <cmath> #include <queue> #include <deque> #include <string> #include <vector> #define zeros(a) memset(a,0,sizeof(a)) #define ones(a) memset(a,-1,sizeof(a)) #define sc(a) scanf("%d",&a) #define sc2(a,b) scanf("%d%d",&a,&b) #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scs(a) scanf("%s",a) #define sclld(a) scanf("%I64d",&a) #define pt(a) printf("%d\\n",a) #define ptlld(a) printf("%I64d\\n",a) #define rep(i,from,to) for(int i=from;i<=to;i++) #define irep(i,to,from) for(int i=to;i>=from;i--) #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define lson (step<<1) #define rson (lson+1) #define eps 1e-6 #define oo 0x3fffffff #define TEST cout<<"*************************"<<endl const double pi=4*atan(1.0); using namespace std; typedef long long ll; template <class T> inline void read(T &n) { char c; int flag = 1; for (c = getchar(); !(c >= \'0\' && c <= \'9\' || c == \'-\'); c = getchar()); if (c == \'-\') flag = -1, n = 0; else n = c - \'0\'; for (c = getchar(); c >= \'0\' && c <= \'9\'; c = getchar()) n = n * 10 + c - \'0\'; n *= flag; } int Pow(int base, ll n, int mo) { if (n == 0) return 1; if (n == 1) return base % mo; int tmp = Pow(base, n >> 1, mo); tmp = (ll)tmp * tmp % mo; if (n & 1) tmp = (ll)tmp * base % mo; return tmp; } //*************************** int n,k,m; const int maxn=100000+10; int a[maxn]; ll sum[maxn]; struct T { int id,l,r; void init(int _id,int _l,int _r) { id=_id,l=_l,r=_r; } }y[maxn]; struct Y { int id,p,dir; void init(int _id,int _p,int _dir) { id=_id,p=_p,dir=_dir; } }x[maxn<<1]; bool cmp(struct Y b,struct Y c) { if(b.p==c.p) return b.dir<c.dir; return b.p<c.p; } int index[maxn]; int pt[maxn]; void sovle() { ll ans=0; zeros(pt); zeros(index); int head=1,sz=0,flag=-1; rep(i,1,2*m) { if(x[i].dir==0) { index[head]=x[i].id; pt[x[i].id]=head; head++,sz++; if(sz==k) flag=head-1; } else { if(sz>=k) { ans=Max(ans,sum[x[i].p]-sum[y[index[flag]].l-1]); if(pt[x[i].id]<=flag&&sz-1>=k) { flag++; while(index[flag]==-1&&flag<=head) { flag++; } } } sz--; index[pt[x[i].id]]=-1; } } ptlld(ans); } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif while(~sc3(n,k,m)) { rep(i,1,n) sc(a[i]); sum[0]=0; sum[1]=a[1]; rep(i,2,n) sum[i]=sum[i-1]+a[i]; int l,r; rep(i,1,m) { sc2(l,r); x[i*2-1].init(i,l,0); x[i*2].init(i,r,1); y[i].init(i,l,r); } sort(x+1,x+1+2*m,cmp); sovle(); } }
思路:这个题目可归类为01分数规划里总结果了,所以已经链接到那篇博文了
2016"百度之星" - 初赛(Astar Round2A)
1001 ALL X
思路:x*(10n-1)/9,之后的应该就简单了
1002 Sitting in Line
这个已经再博客里写过了,所以把标题已经连接到写的那个博客了
思路:这个题要求一个子树里的最大值。先dfs一遍整棵树,并且记录一个点进入时候的id和出去的id,那么这两个id之间就是这个点的子树了。然后利用线段树处理一下,nlogn复杂度
/************************************************************** Problem:hdu 5692 User: youmi Language: C++ Result: Accepted Time:2355MS Memory:14932K ****************************************************************/ #pragma comment(linker, "/STACK:1024000000,1024000000") //#include<bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <stack> #include <set> #include <sstream> #include <cmath> #include <queue> #include <deque> #include <string> #include <vector> #include <ctime> #define zeros(a) memset(a,0,sizeof(a)) #define ones(a) memset(a,-1,sizeof(a)) #define sc(a) scanf("%d",&a) #define sc2(a,b) scanf("%d%d",&a,&b) #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scs(a) scanf("%s",a) #define sclld(a) scanf("%I64d",&a) #define pt(a) printf("%d\\n",a) #define ptlld(a) printf("%I64d\\n",a) #define rep(i,from,to) for(int i=from;i<=to;i++) #define irep(i,to,from) for(int i=to;i>=from;i--) #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define lson (step<<1) #define rson (lson+1) #define eps 1e-6 #define oo 0x3fffffff #define TEST cout<<"*************************"<<endl const double pi=4*atan(1.0); using namespace std; typedef long long ll; ll n,m; ll z,x,y; const int maxn=100000+10; int in[maxn],out[maxn]; ll val[maxn]; ll dp[maxn]; int head[maxn]; int T=0,id; struct side { int v,next; }e[maxn]; struct segment { int l,r; ll mx,cg; void init(ll a,ll b,ll c,ll d) { l=a,r=b,mx=c,cg=d; } }seg[maxn<<2]; inline ll read() { ll x=0,f=1; char ch=getchar(); while (ch<\'0\'||ch>\'9\') {if (ch==\'-\') f=-1; ch=getchar();} while (ch>=\'0\'&&ch<=\'9\') {x=x*10+ch-\'0\'; ch=getchar();} return x*f; } void init() { T=0; id=0; ones(head); } void build(int u,int v) { e[T].v=v; e[T].next=head[u]; head[u]=T++; } void dfs(int u,int f,ll c) { in[u]=++id; if(u==0) dp[id]=c; else dp[id]=dp[in[f]]+c; for(int i=head[u];~i;i=e[i].next) { int v=e[i].v; if(v!=f) dfs(v,u,val[v]); } out[u]=id; } void pushup(int step) { seg[step].mx=Max(seg[lson].mx,seg[rson].mx); } void pushdown(int step) { seg[lson].mx+=seg[step].cg; seg[rson].mx+=seg[step].cg; seg[lson].cg+=seg[step].cg; seg[rson].cg+=seg[step].cg; seg[step].cg=0; } void build(int step,int l,int r) { seg[step].init(l,r,0,0); if(l==r) { seg[step].init(l,r,dp[l],0); return; } int mid=(l+r)>>1; build(lson,l,mid); build(rson,mid+1,r); pushup(step); } void update(int step,int l,int r,ll c) { if(seg[step].l==l&&seg[step].r==r) { seg[step].cg+=c; seg[step].mx+=c; return ; } pushdown(step); int mid=(seg[step].l+seg[step].r)>>1; if(l>mid) update(rson,l,r,c); else if(mid>=r) update(lson,l,r,c); else { update(lson,l,mid,c); update(rson,mid+1,r,c); } pushup(step); } ll query(int step,int l,int r) { if(seg[step].l==l&&seg[step].r==r) { return seg[step].mx; } pushdown(step); int mid=(seg[step].l+seg[step].r)>>1; if(l>mid) return query(rson,l,r); else if(mid>=r) return query(lson,l,r); else { ll temp=query(lson,l,mid); temp=Max(temp,query(rson,mid+1,r)); return temp; } } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif int T_T; scanf("%d",&T_T); for(int kase=1;kase<=T_T;kase++) { printf("Case #%d:\\n",kase); n=read(),m=read(); ll u,v; init(); rep(i,1,n-1) { u=read(),v=read(); build(u,v); build(v,u); } rep(i,0,n-1) { u=read(); val[i]=u; } dfs(0,-1,val[0]); build(1,1,n); rep(i,1,m) { z=read(),x=read(); if(z==1) ptlld(query(1,in[x],out[x])); else { y=read(); ll temp=y-val[x]; update(1,in[x],out[x],temp); val[x]+=temp; } } } return 0; }
1005 BD String
思路:
1---B
2---BBD
3---BBD|B|BDD
4---BBD|B|BDD|B|BBD|D|BDD
5---BBD|B|BDD|B|BBD|D|BDD|B|BBD|B|BDD|D|BBD|D|BDD
从第五行可看出规律:每8个为一组,其中BBD,BDD连续重复;4的倍数上对应的字母,又是题给规律的出现,那么这部分进行dfs即可;然后对于小于等于8的部分,可以用一个数组预处理。
注意:(小于等于8的部分)与(4的倍数)在位置为4的地方重复计算了一次,所以要去掉这一部分
/************************************************************** Problem:hdu 5694 User: youmi Language: C++ Result: Accepted Time:0MS Memory:1572K ****************************************************************/ //#pragma comment(linker, "/STACK:1024000000,1024000000") //#include<bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <stack> #include <set> #include <sstream> #include <cmath> #include <queue> #include <deque> #include &以上是关于2016百度之星 补题记的主要内容,如果未能解决你的问题,请参考以下文章