码迷,mamicode.com
首页 > 其他好文 > 详细

17.10.02

时间:2017-10-02 10:07:44      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:pop   bar   ack   names   als   front   include   tmp   lower   

  • 上午
    • 入门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;
        }
  • 下午
  • 晚上
  • End:

17.10.02

标签:pop   bar   ack   names   als   front   include   tmp   lower   

原文地址:http://www.cnblogs.com/zj75211/p/7619709.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!