zoukankan      html  css  js  c++  java
  • HR#7 题解

    T1

    签到题

    #include<bits/stdc++.h>
    #define R register int
    using namespace std;
    inline int g() { R x=0,f=1;
    	register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
    	do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*f;
    }
    int n,p[101],d[101];
    int main() {
    	n=g(); for(R i=1;i<=n;++i) p[i]=g(),d[i]=g();
    	for(R i=1;i<=n;++i) for(R j=1;j<=n;++j) {
    		if(p[i]+d[i]==p[j]&&p[i]==p[j]+d[j]) return puts("= ="),0;
    	}	puts("O O");
    }
    

    T2

    想一下,发现对应进制Base的奇数幂的位置必须是0。
    每一位都可以是 (0)~(K-1) ,所以我们直接计算每个长度的答案累加就好,注意要特判最高位是否是偶数幂,若是,则要有最高位的限制。

    #include<bits/stdc++.h>
    #define R register int
    #define ll long long
    using namespace std;
    namespace Luitaryi {
    inline ll g() { register ll x=0,f=1;
    	register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
    	do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*f;
    }
    ll n,x,k,ans,anss; int mem[20],t;
    inline void main() {
    	x=n=g(),k=g(); while(x) mem[++t]=x%k,x/=k;
    	ans=1;
    	for(R i=1;i<t;i+=2) ans+=ans*(k-1); anss=ans;
    	if(t&1) for(R i=1;i<=mem[t];++i) anss+=ans;
    	printf("%lld
    ",anss);
    }	
    } signed main() {Luitaryi::main(); return 0;}
    

    T3

    通过观察(?),发现,只有冗余 (2*2) 的格子时,我们无法正确计算能填几个 (1*3) 的,于是判掉。。。。。
    剩下的直接贪心,排序后取前几个 (显然)

    #include<bits/stdc++.h>
    #define R register int
    using namespace std;
    namespace Luitaryi {
    inline int g() { R x=0,f=1;
    	register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
    	do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*f;
    } const int N=10010;
    int T,n,m,k1,k2,ans,Lim;
    int w1[N],w2[N];
    inline void main() {
    	T=g(); while(T--) { ans=0;
    		n=g(),m=g(),k1=g(),k2=g();
    		for(R i=1;i<=k1;++i) w1[i]=g();
    		for(R i=1;i<=k2;++i) w2[i]=g();
    		sort(w1+1,w1+k1+1,greater<int>());
    		sort(w2+1,w2+k2+1,greater<int>());
    		for(R i=1;i<=k1;++i) w1[i]+=w1[i-1];
    		for(R i=1;i<=k2;++i) w2[i]+=w2[i-1];
    		if(n%3==2&&m%3==2&&(n==2||m==2)) //冗余2*2的格子,而 2*2 的格子不能用 1*3 的物品去填的 
    			Lim=n*m-4;
    		else Lim=n*m-n*m%3;
    		for(R i=0,lim=min(k2,Lim/3);i<=lim;++i) 
    			ans=max(ans,w2[i]+w1[min(k1,(n*m-i*3)/2)]);
    		printf("%d
    ",ans);
    	}
    }
    } signed main() {Luitaryi::main(); return 0;}
    

    T4

    考试时只会插板,dp预处理不会。

    #include<iostream>
    #include<cstdio>
    #define R register int
    #define ll long long
    using namespace std;
    namespace Luitaryi {
    inline ll g() { register ll x=0,f=1;
    	register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
    	do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*f;
    } const int N=100,M=905229641;
    int m,ans,Inv[N+1],fac[N+1],f[N*N][N]; ll n;
    inline int C(ll n,int m) { R ret=1;
    	for(R i=1;i<=m;++i) ret=1ll*ret*Inv[i]%M*((n-m+i)%M)%M; return ret;
    }
    inline void main() {
    	Inv[0]=Inv[1]=1; for(R i=2;i<=N;++i) Inv[i]=M-1ll*M/i*Inv[M%i]%M;
    	fac[0]=fac[1]=1; for(R i=2;i<=N;++i) fac[i]=1ll*fac[i-1]*i%M;
    	n=g(),m=g(); f[0][0]=1; //f[j][i] 和为j,i个 %m 不同余的数 
    	for(R t=0;t<m;++t) for(R j=m*(m-1)/2;j>=t;--j) for(R i=m;i>=1;--i)
    		f[j][i]=(f[j][i]+f[j-t][i-1])%M;
    	//枚举填的是什么数(模意义下),枚举填了几个,枚举总和。(01背包) 
            //之所以要记填了几个,是因为后面插板要用
    	for(R i=0,lim=min(m*(m-1)/2ll,n);i<=lim;++i) { //枚举可以自由分配的部分 
    		if((n-i)%m) continue; register ll k=(n-i)/m;
    		for(R j=1;j<=m;++j) ans=(ans+1ll*f[i][j]*C(k+j-1,j-1)%M*fac[j])%M;//插板,注意是有序的 
    	} printf("%d
    ",ans);
    }
    } signed main() {Luitaryi::main(); return 0;}
    

    T5

    首先有一个十分 naive 的做法:

    #include<bits/stdc++.h>
    #define R register int
    using namespace std;
    namespace Luitaryi {
    inline int g() { R x=0,f=1;
    	register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
    	do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*f;
    } int n;
    char s[30],c[100010];
    inline void ck(int l,int r) { 
    	c[l]=1,c[r]=0;
    	if(l+1==r) return ;
    	printf("? %d %d",l+1,r-1);
    	cout<<endl<<flush;
    	scanf("%s",s);
    	if(s[0]=='Y') ck(l+1,r-1);
    	else {
    		if(l+3==r) {
    			c[l]=1,c[l+1]=0,c[l+2]=1,c[l+3]=0; return ;
    		}
    		for(R p=l+1;p<r&&l<r;p+=2) {
    			printf("? %d %d",l,p);
    			cout<<endl<<flush;
    			scanf("%s",s);
    			//flush(stdin);
    			if(s[0]=='Y') {ck(l,p),ck(p+1,r); return ;}
    		}
    	}
    }
    inline void main() {
    	n=g(); 
    	ck(1,n);
    	putchar('!');putchar(' ');
    	for(R i=1;i<=n;++i) putchar(c[i]?'(':')'); cout<<endl<<flush<<endl;
    }
    } signed main() {Luitaryi::main(); return 0;}
    

    只是充充数
    上面的代码含义是递归每个 合法的 区间,我们发现,如果区间是合法的,最左边一定是 '(' ,**最右边一定是 ** ')' 。
    于是一个合法区间可能由一个或多个合法子区间组成,于是递归。
    递归边界是两个合法括号"()"或四个"()()"
    好的显然他询问次数过多

    但是注意到,我们在上面没有好好 利用每一次询问得到的信息 ,所以他萎了。
    注意一下上次的递归边界,若有两个括号,且合法,那一定是"()",这种是真正有用的信息。
    我们怎么利用呢?我们可以一直询问相邻两个,若合法,就把他们去掉,这样包含他们的两个括号就相连了,即我们可以接着尝试扩展合法区间。
    具体的,我们可以用一个栈维护这个过程:若栈中为空,当前指针入栈;若栈中的括号与现在指针构成的区间合法,弹栈;否则当前指针入栈;
    复杂度(mathcal{O}(n))

    #include<bits/stdc++.h>
    #define R register int
    using namespace std;
    namespace Luitaryi {
    inline int g() { R x=0,f=1;
    	register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
    	do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*f;
    }
    int n,stk[100010],top;
    char s[30],c[100010];
    inline void main() {
    	n=g(); stk[++top]=1; R p=2;
    	while(p<=n) {
    		if(!top) stk[++top]=p,++p;
    		printf("? %d %d",stk[top],p);
    		cout<<endl<<flush;
    		scanf("%s",s); if(s[0]=='Y'){
    			c[stk[top]]=1,c[p]=0; --top;
    		} else stk[++top]=p;
    		//p+=2;
    		++p;
    	} putchar('!');putchar(' ');
    	for(R i=1;i<=n;++i) putchar(c[i]?'(':')'); cout<<endl<<flush<<endl;
    }
    } signed main() {Luitaryi::main(); return 0;}
    
  • 相关阅读:
    shell 10流程控制
    shell 9test命令
    shell 8字符串与文件内容处理
    shell 7输入输出
    shell 6基本运算符
    JS-JQ实现TAB选项卡
    JS-JQ实现页面滚动时元素智能定位(顶部-其他部位)
    js获取框架(IFrame)的内容
    codeforces 660C C. Hard Process(二分)
    codeforces 660B B. Seating On Bus(模拟)
  • 原文地址:https://www.cnblogs.com/Jackpei/p/11689006.html
Copyright © 2011-2022 走看看