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

    传送门

    (A)

    什么玩意儿……

    const int N=105;
    char s[N];int n,f1,f2;
    int main(){
    	scanf("%s",s+1),n=strlen(s+1);
    	fp(i,1,n)if(s[i]=='C')f1=1;
    		else if(f1&&s[i]=='F')f2=1;
    	puts(f2?"Yes":"No");
    	return 0;
    }
    

    (B)

    什么玩意儿……

    const int N=105;
    int a[N],n,k,mx;
    int main(){
    	scanf("%d%d",&k,&n);
    	fp(i,1,n)scanf("%d",&a[i]),cmax(mx,a[i]);
    	printf("%d
    ",(mx<<1)<=k?0:mx-(k-mx)-1);
    	return 0;
    }
    

    (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;
    const int P=1e9+7;
    inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
    inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
    inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
    inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
    int ksm(R int x,R int y){
    	R int res=1;
    	for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
    	return res;
    }
    const int N=5e5+5;
    int a[N],b[N],c[N],n,res=1;
    inline int min(R int x,R int y){return x<y?x:y;}
    int main(){
    	scanf("%d",&n);
    	fp(i,1,n)scanf("%d",&b[i]);
    	fp(i,1,n)scanf("%d",&c[i]);
    	fp(i,1,n)if(b[i]!=b[i-1])a[i]=b[i];
    	fd(i,n,1)if(c[i]!=c[i+1])a[i]=c[i];
    	for(R int i=1,mx=0;i<=n;++i){
    		cmax(mx,a[i]);
    		if(mx!=b[i])return puts("0"),0;
    	}
    	for(R int i=n,mx=0;i;--i){
    		cmax(mx,a[i]);
    		if(mx!=c[i])return puts("0"),0;
    	}
    	fp(i,1,n)if(!a[i])res=mul(res,min(b[i],c[i]));
    	printf("%d
    ",res);
    	return 0;
    }
    

    (D)

    首先发现每两列之间是互相独立的,也就是说如果我们算出每相邻两列的答案,最后加起来就是最终的答案了,证明就不写了

    然后问题转化为计算两列之间的答案,方便起见沿对角线翻转一下,记(f[i][j])表示前一行还剩下(i)的前缀,后一行还剩下(j)的前缀,最小代价为多少,最后(f[m][m])就是答案

    (f)的转移显然,唯一的问题在于计算(g[i][j])表示前一行(i)的前缀和后一行(j)的前缀,这种状态下有多少是重合的,暴力计算(O(n^3)),前缀和优化一下就可以(O(n^2))

    最后总复杂度(O(n^3)),具体细节可以看代码

    //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=305;
    char mp[N][N],s[N][N];int f[N][N],n,m,res;
    int calc(R int id){
    	fp(i,1,m)fp(j,1,m)f[i][j]=(s[id][i]==s[id+1][j]);
    	fp(i,1,m)fp(j,1,m)f[i][j]+=f[i-1][j-1];
    	fp(i,1,m)fp(j,1,m)f[i][j]+=min(f[i-1][j],f[i][j-1]);
    	return f[m][m];
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	scanf("%d%d",&n,&m);
    	fp(i,1,n)scanf("%s",mp[i]+1);
    	fp(i,1,n)fp(j,1,m)s[j][i]=mp[i][j];
    	swap(n,m);
    	fp(i,1,n-1)res+=calc(i);
    	printf("%d
    ",res);
    	return 0;
    }
    

    (E)

    根据康托展开,一个排列(p_i)在所有排列中的排名为(sumlimits_{i=1}^na_i(n-i)!),其中(a_i)表示满足(j>i)(p_j<p_i)(j)的个数,即对于一个逆序对((i,j)),对答案的贡献是((n-i)!)

    那么我们对于(i,j)为已知数和未知数的情况分别考虑就好了,具体细节看代码

    //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 P=1e9+7;
    inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
    inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
    inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
    inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
    int ksm(R int x,R int y){
    	R int res=1;
    	for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
    	return res;
    }
    const int N=5e5+5;
    int c[N],s[N],suf[N],a[N],vis[N],fac[N],cnt,m,n,res,sum;
    inline void chg(R int x){for(;x<=n;x+=x&-x)++c[x];}
    inline int query(R int x){R int res=0;for(;x;x-=x&-x)res+=c[x];return res;}
    int main(){
    //	freopen("testdata.in","r",stdin);
    	scanf("%d",&n),m=n;
    	fp(i,1,n){
    		scanf("%d",&a[i]);
    		if(a[i])++s[a[i]],--m;
    	}
    	fp(i,1,n)suf[i]=s[i]=1-s[i],s[i]+=s[i-1];
    	fd(i,n,1)suf[i]+=suf[i+1];
    	fac[0]=1;fp(i,1,n)fac[i]=mul(fac[i-1],i);
    	fd(i,n,1)if(!a[i])++cnt;
    		else{
    			sum=mul(query(a[i]-1),fac[m]);
    			if(cnt)upd(sum,1ll*cnt*s[a[i]]%P*fac[m-1]%P);
    			upd(res,mul(sum,fac[n-i]));
    			chg(a[i]);
    		}
    	cnt=sum=0;
    	fp(i,1,n)if(!a[i])upd(sum,fac[n-i]),++cnt;
    		else if(cnt)upd(res,1ll*sum*suf[a[i]]%P*fac[m-1]%P);
    	sum=(1ll*m*(m-1)>>1)%P,cnt=0;
    	if(m>=2)fp(i,1,n)if(!a[i])++cnt,upd(res,1ll*sum*(m-cnt)%P*fac[m-2]%P*fac[n-i]%P);
    	upd(res,fac[m]); 
    	printf("%d
    ",res);
    	return 0;
    }
    
  • 相关阅读:
    图片上传功能(html+js)
    Dom元素基本操作方法API(转载)非原创
    使用jquery mobile笔记(更新中)
    基于ASP.NET AJAX的WebPart开发与部署
    Workbooks 对象的 Open 方法参数说明
    使用properties和SPContext时须小心
    转载 C# 与 C++ 数据类型对照
    ASP.NET实现进度条
    为sharepoint的内部页面添加后台代码
    操作Word Application.Documents.Open方法参数说明
  • 原文地址:https://www.cnblogs.com/yuanquming/p/11487083.html
Copyright © 2011-2022 走看看