zoukankan      html  css  js  c++  java
  • Wannafly挑战赛26题解

    为啥混进了几道不是魔禁的题……出题人太不敬业了……

    传送门

    (A) 御坂网络

    为啥没有番外个体和整体意志呢

    暴力模拟就好了,这个要是都打错我干脆滚回去学文化课算了

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define ll long long
    #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)
    using namespace std;
    const int N=1005;
    int x[N],y[N],n;double d;
    inline ll dis(R int i,R int j){return 1ll*(x[i]-x[j])*(x[i]-x[j])+1ll*(y[i]-y[j])*(y[i]-y[j]);}
    bool ck(R int id){
    	fp(i,1,n)if(id!=i&&dis(id,i)!=d)return false;
    	return true;
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	scanf("%d",&n);
    	fp(i,1,n)scanf("%d%d",&x[i],&y[i]);
    	d=dis(1,2);if(ck(1))return puts("1"),0;
    	fp(i,2,n)if(d=dis(1,i),ck(i))return printf("%d
    ",i),0;
    	puts("-1");
    	return 0;
    }
    

    (B) 冥土追魂

    首先我们发现一件事情,肯定是若干行全都被拿走,然后剩下那些不够(m)次的全都集中在一行。这个贪心的正确性显然

    那么我们把所有的行按(sum)排列,然后枚举一下哪一行是选那些不够(m)次的就好了

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define ll long long
    #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 cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    const int N=1005;
    int mp[N][N],id[N];ll res,mn,ret,sum[N],r[N];
    int n,m,k;
    inline bool qwq(const int &x,const int &y){return x>y;}
    inline bool cmp(const int &x,const int &y){return sum[x]==sum[y]?r[x]>r[y]:sum[x]<sum[y];}
    int main(){
    //	freopen("testdata.in","r",stdin);
    	n=read(),m=read(),k=read();
    	fp(i,1,n)fp(j,1,m)mp[i][j]=read(),sum[i]+=mp[i][j];
    	fp(i,1,n)id[i]=i,sort(mp[i]+1,mp[i]+1+m,qwq);
    	fp(i,1,n)fp(j,1,k%m)r[i]+=mp[i][j];
    	sort(id+1,id+1+n,cmp);
    	fp(i,1,k/m)ret+=sum[id[i]];
    	if(k==n*m)return printf("%lld
    ",ret),0;
    	res=1e18;
    	fp(i,1,k/m)cmin(res,ret-sum[id[i]]+r[id[i]]+sum[id[k/m+1]]);
    	fp(i,k/m+1,n)cmin(res,ret+r[id[i]]);
    	printf("%lld
    ",res);
    	return 0;
    }
    

    (C) 七彩线段

    如果只有一种颜色的话,我们可以把坐标离散化一下,直接用树状数组维护(dp)就可以了

    因为颜色不超过(7)种,我们把所有线段按右端点排序,然后再记录一个(2^7)的状态表示颜色就可以了

    //minamoto
    #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;}
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    const int N=1e5+5;
    struct node{
    	int l,r,len,col;
    	node(){}
    	node(R int li,R int ri,R int L,R int C):l(li),r(ri),len(L),col(C){}
    	inline bool operator <(const node &b)const{return r==b.r?l<b.l:r<b.r;}
    }st[N];
    int b[N<<1],l[N],r[N],col[N],c[N<<1][135],len[N],sz[255];
    int n,m,top,tot,res,k,t;
    inline void upd(R int x,R int y,R int id){for(;x<=tot;x+=x&-x)cmax(c[x][id],y);}
    inline int query(R int x,R int id){R int res=-1;for(;x;x-=x&-x)cmax(res,c[x][id]);return res;}
    int main(){
    //	freopen("testdata.in","r",stdin);
    	n=read(),m=read(),res=-1,b[tot=1]=0;
    	fp(i,1,n)b[++tot]=l[i]=read(),b[++tot]=r[i]=read(),col[i]=read()-1,len[i]=r[i]-l[i];
    	sort(b+1,b+1+tot),tot=unique(b+1,b+1+tot)-b-1;
    	fp(i,1,n)l[i]=lower_bound(b+1,b+1+tot,l[i])-b,r[i]=lower_bound(b+1,b+1+tot,r[i])-b;
    	fp(i,1,n)st[i]=node(l[i],r[i],len[i],col[i]);
    	fp(s,1,127)sz[s]+=sz[s>>1]+(s&1);
    	sort(st+1,st+1+n);
    	memset(c,-1,sizeof(c));
    	fp(i,0,tot)c[i][0]=0;
    	fp(i,1,n){
    		fp(s,0,127)if(sz[s]<=m){
    			k=query(st[i].l-1,s),t=(s|(1<<st[i].col));
    			if(k!=-1)upd(st[i].r,k+st[i].len,t);
    			if(sz[t]==m)cmax(res,k+st[i].len);
    		}
    	}
    	printf("%d
    ",res);
    	return 0;
    }
    

    (D) 禁书目录

    完美地漏过了所有特殊情况的考虑

    首先,我们假设元素(i)(a_i)从大到小排序的话,它的排名为(c),那么它有用的概率就是({1over c})

    证明的话……只考虑比它大的以及它自己这(c)个元素,显然只有它排在最前面的序列是有用的,所以有用的序列((c-1)!)个,那么它可以用的概率就是({(c-1)!over c!}={1over c})

    把每个元素的排名预处理出来,那么对于一个元素,它没有用的概率是(1-{1over c})。我们可以对于每一个(b)计算有多少序列它不存在,就是所有(b_i=b)的元素全都不合法的概率,直接乘起来就好了

    然后有一个比较尴尬的问题就是有可能两个元素(a_i=a_j)(b_i=b_j),这种情况下我们就不能简单把这两个变量看做独立的了,一个解决办法是钦定其中某一个必须排在前面,然后按上面的计算就可以了

    //minamoto
    #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;}
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    const int N=5e5+5,P=998244353;
    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;
    }
    int a[N],b[N],inv[N],rk[N],id[N],fac,n,k,res,mc;
    inline bool ccmp(const int &x,const int &y){return a[x]>a[y];}
    inline bool cmp(const int &x,const int &y){return b[x]<b[y];}
    #define p(i) inv[rk[id[i]]]
    int main(){
    //	freopen("testdata.in","r",stdin);
    	n=read(),inv[0]=inv[1]=1,fac=1;
    	fp(i,1,n)a[i]=read(),b[i]=read(),fac=mul(fac,i),id[i]=i;
    	fp(i,2,n)inv[i]=mul(P-P/i,inv[P%i]);
    	sort(id+1,id+1+n,ccmp);
    	fd(i,n,1)rk[id[i]]=(a[id[i+1]]==a[id[i]]?rk[id[i+1]]:i);
    	stable_sort(id+1,id+1+n,cmp);//如果两个元素相等,stable_sort不会改变它们的相对顺序 
    	for(R int i=1,j=1;i<=n;i=j+1,j=i){
    		while(j<n&&b[id[j+1]]==b[id[j]])++j;
    		mc=P+1-p(i);
    		fp(k,i+1,j){
    			if(a[id[k]]==a[id[k-1]])rk[id[k]]=rk[id[k-1]]-1;
    			mc=mul(mc,P+1-p(k));
    		}
    		res=add(res,P+1-mc);
    	}
    	res=mul(res,fac);
    	printf("%d
    ",res);
    	return 0;
    }
    

    剩下的先咕咕咕了

  • 相关阅读:
    《Cracking the Coding Interview》——第12章:测试——题目2
    《Cracking the Coding Interview》——第12章:测试——题目1
    《Cracking the Coding Interview》——第10章:可扩展性和存储空间限制——题目7
    《Cracking the Coding Interview》——第10章:可扩展性和存储空间限制——题目6
    了解/从事机器学习/深度学习系统相关的研究需要什么样的知识结构?
    luoguP1025+codevs 1039 数的划分 x
    luogu P1223 排队接水 x
    luogu P1181 数列分段Section I x
    luogu P2661 信息传递 x
    luoguP1186 玛丽卡 x
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10624626.html
Copyright © 2011-2022 走看看