DISCO Presents Discovery Channel Code Contest 2020 Qual题解

传送门

(A)

咕咕

int x,y;
int c[4]={0,300000,200000,100000};
int res;
int main(){
	cin>>x>>y;
	if(x<=3)res+=c[x];
	if(y<=3)res+=c[y];
	if(x==1&&y==1)res+=4e5;
	cout<<res<<endl;
	return 0;
}

(B)

咕咕

const int N=2e5+5;
typedef long long ll;
int a[N],n;ll sum[N],suf[N],res;
int main(){
	scanf("%d",&n);
	fp(i,1,n)scanf("%d",&a[i]),sum[i]=suf[i]=a[i];
	fp(i,1,n)sum[i]+=sum[i-1];fd(i,n,1)suf[i]+=suf[i+1];
	res=1e18;
	fp(i,1,n-1)cmin(res,abs(sum[i]-suf[i+1]));
	printf("%lld
",res);
	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 N=305;
char mp[N][N];int col[N][N],n,m,cnt,K;
int main(){
	scanf("%d%d%d",&n,&m,&K);
	fp(i,1,n)scanf("%s",mp[i]+1);
	fp(i,1,n)fp(j,1,m)if(mp[i][j]=='#'){
		col[i][j]=++cnt;
		for(R int k=j-1;k&&!col[i][k]&&mp[i][k]!='#';--k)col[i][k]=cnt;
		for(R int k=j+1;k<=m&&!col[i][k]&&mp[i][k]!='#';++k)col[i][k]=cnt;
	}
	fp(i,1,n)fp(j,1,m)if(col[i][j]){
		for(R int k=i-1;k&&!col[k][j];--k)col[k][j]=col[i][j];
		for(R int k=i+1;k<=n&&!col[k][j];++k)col[k][j]=col[i][j];
	}
	fp(i,1,n)fp(j,1,m)printf("%d%c",col[i][j]," 
"[j==m]);
	return 0;
}

(D)

傻了,什么神仙题

我们发现一次操作要么使总位数减1总和不变,要么使总和减9总位数不变,而最终的情况一定是位数为1总和小于等于9,记总位数为d,总和为s,答案就是(d-1+(s-1)/9)

const int N=2e5+5;
typedef long long ll;
int d[N],n;ll c[N],res,sum;
int main(){
	scanf("%d",&n);
	fp(i,1,n)scanf("%d%lld",&d[i],&c[i]),sum+=c[i],res+=d[i]*c[i];
	printf("%lld
",(res-1)/9+sum-1);
	return 0;
}

(E)

我们记(d(i)=query(i,i+n-1)),如果存在某个(d(i) eq d(i+1)),那么显然(i)(i+n)的颜色就可以知道了,同时((i+1,i+n-1))这个区间中一定是红蓝次数各一半,我们可以用它去check出其他所有颜色

所以问题是怎么找到这个分界点,它实际上是可以二分的,我们初始时记(l=1,r=n+1),那么(d(l) eq d(r))显然成立,我们每一次判断(mid),如果(d(mid)=d(l))则令(l=mid),否则令(r=mid),这样一直二分到(r-l=1)即可

//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=505;
char s[5];int a[N],col[N],bs[N],cnt[2],n,las,now,ql,qr,l,r,mid,ans;
inline int ask(R int l,R int r){
	putchar('?'),putchar(' ');
	fp(i,l,r)printf("%d ",i);
	putchar('
'),fflush(stdout);
	scanf("%s",s+1);return s[1]=='R';
}
inline int ask(R int l,R int r,R int x,R int d){
	putchar('?'),putchar(' ');
	fp(i,l,r)if(i!=x)printf("%d ",i);
	if(d)printf("%d ",x);
	putchar('
'),fflush(stdout);
	scanf("%s",s+1);
	if(s[1]=='-')while(true);
	return s[1]=='R';
}
int main(){
//	freopen("testdata.in","r",stdin);
	scanf("%d",&n);
	fp(i,1,n<<1)col[i]=-1;
	l=1,r=n+1,ans=0,bs[1]=ask(1,n),bs[n+1]=bs[1]^1;
	while(r-l>1){
		mid=(l+r)>>1,bs[mid]=ask(mid,mid+n-1);
		bs[mid]==bs[l]?l=mid:r=mid;
	}
	col[l]=bs[l],col[r+n-1]=bs[r];
	ql=r,qr=r+n-2;
	fp(i,ql,qr)col[i]=ask(ql-1,qr+1,i,0)^1;
	fp(i,1,ql-2)col[i]=ask(ql,qr,i,1);
	fp(i,qr+2,n<<1)col[i]=ask(ql,qr,i,1);
	putchar('!'),putchar(' ');
	fp(i,1,n<<1)putchar(col[i]?'R':'B');
	putchar('
'),fflush(stdout);
	return 0;
}

(F)

首先,可以发现如果一个状态转移一次之后每个格子都有一个机器人,那么这个状态肯定是合法的

如果一直往下走,那么循环节就是(g={nover gcd(n,T)}),往右走循环节是(h={mover gcd(m,T)}),那么这个(g imes h)的子矩形只会受自己内部影响,和外面无关,所以我们可以对于每个这样的子矩形单独考虑

这样我们可以把问题转化为一个(g imes h)的子矩形且(T=1),我们考虑合法的方案,一种是存在某个格子不走,那么整个矩形全都不走,一种是分别考虑每行,要么不走要么全往右,一种是每列都是全往下,这个直接组合数算一下,全都不走的情况也会在后两种里被算到,要去掉

还有一种情况是既往右又往下,假设我们先固定((1,1))为右,那么((1,2))就不能被((n,2))走到了,所以((n,2))也必然是右,以此类推我们可以确定({h imes gover gcd(h,g)})个格子,那么对于所有(gcd(h,g))个格子每个都有两种方案,直接算一下就好了,记得把全往右和全往下的情况也去掉

//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 P=1e9+7;
inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
inline int inc(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 ll y){
	R int res=1;
	for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
	return res;
}
int n,m,T,res,h,g;
int main(){
	scanf("%d%d%d",&n,&m,&T);
	h=n/__gcd(n,T),g=m/__gcd(m,T);
//	printf("%d %d
",h,g);
	res=((0ll+1+ksm(2,h)-1+ksm(2,g)-1+ksm(2,__gcd(h,g))-2)%P+P)%P;
	res=ksm(res,1ll*(n/h)*(m/g));
	printf("%d
",res);
	return 0;
}
原文地址:https://www.cnblogs.com/yuanquming/p/11921562.html