zoukankan      html  css  js  c++  java
  • CODE FESTIVAL 2016 qual B题解

    传送门

    (A)

    什么玩意儿……

    const char t[]={"0CODEFESTIVAL2016"};
    char s[25];int res;
    int main(){
    	scanf("%s",s+1);
    	fp(i,1,16)res+=s[i]!=t[i];
    	printf("%d
    ",res);
    	return 0;
    }
    

    (B)

    什么玩意儿……

    const int N=1e5+5;
    char s[N];int a,b,n,c,cc;
    int main(){
    	scanf("%d%d%d%s",&n,&a,&b,s+1),a+=b;
    	fp(i,1,n){
    		switch(s[i]){
    			case 'c':puts("No");break;
    			case 'a':puts(c+1<=a?(++c,"Yes"):"No");break;
    			case 'b':puts(c+1<=a&&cc+1<=b?(++c,++cc,"Yes"):"No");break;
    		}
    	}
    	return 0;
    }
    

    (C)

    显然需要连成一棵树,且贪心选取边来连接,如果当前连的边是左右连接的,且上下连接的边总共连了(c)条,那么说明每一列只有(m+1-c)个连通块了,那么当前边只需要连这么多条

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    typedef long long ll;
    const int N=5e5+5;
    ll res;int a[N],op[N],id[N],top,n,m,c,d;
    inline bool cmp(const int &x,const int &y){return a[x]<a[y];}
    int main(){
    	scanf("%d%d",&n,&m);
    	fp(i,1,n)++top,scanf("%d",&a[top]),op[top]=0,id[top]=top;
    	fp(i,1,m)++top,scanf("%d",&a[top]),op[top]=1,id[top]=top;
    	sort(id+1,id+1+top,cmp);
    	fp(i,1,top){
    //		printf("%d %d %d
    ",id[i],a[id[i]],op[id[i]]);
    		if(!op[id[i]])res+=1ll*a[id[i]]*(m+1-d),++c;
    			else res+=1ll*a[id[i]]*(n+1-c),++d;
    	}
    	printf("%lld
    ",res);
    	return 0;
    }
    

    (D)

    还是贪心,一个贪心是先处理完前面再处理完后面,一个贪心是对于每一个点选择可以卖给他的价格最小的物品卖,记前(i-1)个人中剩余钱数最多的人钱数为(mn),那么卖给第(i)个人的商品价格就是(mn+1),如果(a_i=mn+1)就一个都买不了,并且(++mn),否则我们贪心卖到至少还有一元钱剩余就行了

    然而有一种情况是第(i)个人还剩下恰好(mn+1)元,根据贪心期间肯定是不让(mn)增加最优,那么我们肯定可以在之前得到某一次卖的商品价格(+1),这样就不会令(mn)增加了

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    typedef long long ll;
    const int N=5e5+5,inf=0x3f3f3f3f;
    ll res;int a[N],n,mn;
    int main(){
    	scanf("%d",&n);
    	fp(i,1,n)scanf("%d",&a[i]);
    	res=a[1]-1,mn=1;
    	fp(i,2,n){
    		if(a[i]==mn+1)++mn;
    		else res+=(a[i]-1)/(mn+1);
    	}
    	printf("%lld
    ",res);
    	return 0;
    }
    

    (E)

    首先考虑一个暴力的想法,先把所有的串扔到(trie)树里,然后对于询问直接在(trie)树上匹配这个串,同时把所有字典序小于当前转移的子树里的串的个数加入答案

    这样显然要挂掉,而且我们也不可能(26!)枚举所有字母的大小

    (i,j)为两个不同的转移,考虑到(i)这个转移会对(j)的子树造成贡献,当且仅当重定义之后的字母中(i<j),也就是说会对答案造成影响的总共只有(26 imes 26)种状态

    那么我们对于(trie)树上的每一个节点,记录一个(cnt[p][i]),表示当处于节点(p),且状态为(i)(i)表示一种大小关系,假设它表示(a<b),也就是说(a)这个字母字典序比(b)小),此时按照暴力匹配之后的贡献是多少,即从根节点走到(p)的过程中如果转移是(b)就加上(a)那棵子树的(size),那么(cnt[p][i])表示那些(size)的和

    这样对于一个询问,直接枚举所有的大小关系并加上对应的贡献即可

    复杂度(O((n+q)26^2))

    具体细节可以参考代码

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    const int N=5e5+5,M=676;
    char t[N];int sz[N],size[N],pos[N],fa[N],ch[N][26];
    int id[N],bg[N],len[N],pi[26],n,q,nd;
    vector<int>cnt[N];
    void ins(R int ID,R int len){
    	R int p=0;
    	for(R int i=1,c;i<=len;++i){
    		c=t[i]-'a';
    		if(!ch[p][c])ch[p][c]=++nd;
    		p=ch[p][c],++sz[p];
    	}
    	id[p]=ID,pos[ID]=p;
    }
    void dfs(int p,int ga,int s){
    	fa[p]=ga;if(ga==-1)cnt[p].resize(M),fa[p]=p;
    	if(id[p])++s,size[id[p]]=s;
    	R int cp=0;fp(i,0,25)cp+=(ch[p][i]!=0);
    	ga=fa[p];if(cp>1)ga=-1;
    	fp(i,0,25)if(ch[p][i])dfs(ch[p][i],ga,s);
    }
    void dd(int p,int ga){
    	if(p&&fa[p]==p)fp(i,0,M-1)cnt[p][i]+=cnt[ga][i];
    	fp(i,0,25)if(ch[p][i])fp(j,i+1,25)if(ch[p][j]){
    		cnt[ch[p][i]][j*26+i]+=sz[ch[p][j]];
    		cnt[ch[p][j]][i*26+j]+=sz[ch[p][i]];
    	}
    	fp(i,0,25)if(ch[p][i])dd(ch[p][i],fa[p]);
    }
    int solve(int k){
    	R int res=size[k];
    	fp(i,0,25)fp(j,i+1,25)res+=cnt[fa[pos[k]]][pi[i]*26+pi[j]];
    	return res;
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	scanf("%d",&n);
    	fp(i,1,n)scanf("%s",t+1),len[i]=strlen(t+1),ins(i,len[i]);
    	dfs(0,-1,0);dd(0,-1);
    	scanf("%d",&q);
    	for(R int k;q;--q){
    		scanf("%d%s",&k,t+1);
    		fp(i,1,26)pi[i-1]=t[i]-'a';
    		printf("%d
    ",solve(k));
    	}
    	return 0;
    }
    
  • 相关阅读:
    Atitti 图像处理 图像混合 图像叠加 blend 原理与实现
    Atitit Gaussian Blur 高斯模糊 的原理and实现and 用途
    Atitit 图像处理 灰度图片 灰度化的原理与实现
    Atitit (Sketch Filter)素描滤镜的实现  图像处理  attilax总结
    Atitit 实现java的linq 以及与stream api的比较
    Atitit attilax在自然语言处理领域的成果
    Atitit 图像处理 常用8大滤镜效果 Jhlabs 图像处理类库 java常用图像处理类库
    Atitit 图像处理--图像分类 模式识别 肤色检测识别原理 与attilax的实践总结
    Atitit apache 和guava的反射工具
    atitit。企业的价值观 员工第一 vs 客户第一.docx
  • 原文地址:https://www.cnblogs.com/yuanquming/p/11475730.html
Copyright © 2011-2022 走看看