suxxsfe

一言(ヒトコト)

CF #632 (Div. 2) 对应题号CF1333

1333A Little Artem

在一个\(n\)\(m\)列的格子上染色,每个格子能染黑白两种
构造一种方案,使得四个方向有至少一个白色格子的黑色格子的数量,比四个方向有至少一个黑色格子的白色格子的数量,恰好多一

对于\(n=m\),只要构造一个黑色下三角就行,像这样:

BWWW
BBWW
BBBW
BBBB

考虑其它情况,就是在\(n=m\)的部分也是构造这样的三角,其它的用黑色排成一排或一列
分别是\(n>m\)\(n<m\)两种情况

n>m:
BWWW
BWWW
....
BWWW
BBWW
BBBW
BBBB

n<m:
BWWWW...WWW
BBWWW...WWW
BBBWW...WWW
BBBBW...WWW
BBBBB...BBB

也就是最后一行/第一列全部染成黑色

代码写的有点傻

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#define reg register
#define EN std::puts("")
#define LL long long
inline int read(){
	register int x=0;register int y=1;
	register char c=std::getchar();
	while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
	return y?x:-x;
}
int main(){int T=read();while(T--){
	int n=read(),m=read();
	if(n==m){
		for(reg int i=1;i<=n;i++){
			for(reg int j=1;j<=i;j++) std::putchar('B');
			for(reg int j=i+1;j<=n;j++) std::putchar('W');
			EN;
		}
	}
	else if(n>m){
		for(reg int i=1;i+m<=n;i++){
			std::putchar('B');
			for(reg int j=2;j<=m;j++) std::putchar('W');
			EN;
		}
		for(reg int i=1;i<=m;i++){
			for(reg int j=1;j<=i;j++) std::putchar('B');
			for(reg int j=i+1;j<=m;j++) std::putchar('W');
			EN;
		}
	}
	else{
		for(reg int i=1;i<n;i++){
			for(reg int j=1;j<=i;j++) std::putchar('B');
			for(reg int j=i+1;j<=m;j++) std::putchar('W');
			EN;
		}
		for(reg int j=1;j<=m;j++) std::putchar('B');
		EN;
	}
}
	return 0;
}

CF1333B Kind Anton

有一个数组\(a,a_i\in\{-1,0,1\}\)
做一下变化:选一个\(1\le i<j\le n,a_j=a_i+a_j\)
问能不能通过这种变化,使得它变成数组\(b\)

因为只能把一个\(a_j\)之前的数\((i<j)\)加到\(a_j\)上,所以记录一下在第\(i\)位之前,\(a\)中有没有出现过\(1,-1\)

  • \(b_i>a_i\),此时如果没出现过\(1\),则无解
  • \(b_i<a_i\),此时如果没出现过\(-1\),无解
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#define reg register
#define EN std::puts("")
#define LL long long
inline int read(){
	register int x=0;register int y=1;
	register char c=std::getchar();
	while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
	return y?x:-x;
}
int n;
int a[100006],b[100006];
int have1[100006],have_1[100006];
int main(){int T=read();while(T--){
	n=read();
	for(reg int i=1;i<=n;i++){
		a[i]=read();
		have1[i]|=have1[i-1];have_1[i]|=have_1[i-1];
		if(a[i]==1) have1[i+1]=1;
		else if(a[i]==-1) have_1[i+1]=1;
	}
	for(reg int i=1;i<=n;i++) b[i]=read();
	for(reg int i=n;i;i--){
		if(b[i]>a[i]){
			if(!have1[i]) goto NO;
		}
		else if(b[i]<a[i]){
			if(!have_1[i]) goto NO;
		}
	}
	for(reg int i=1;i<=n+1;i++)
		have1[i]=have_1[i]=0;
	std::puts("YES");
	continue;
	NO:;std::puts("NO");
	for(reg int i=1;i<=n+1;i++)
		have1[i]=have_1[i]=0;
}
	return 0;
}

 

CF1333C Eugene and an array

尺取法
然而比赛的时候没想出来,就会 AB
然后掉了40多分/kk

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<map>
#define reg register
#define EN std::puts("")
#define LL long long
inline int read(){
	register int x=0;register int y=1;
	register char c=std::getchar();
	while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
	return y?x:-x;
}
std::map<LL,int>map;
LL sum[200006];
int n;
//CF1333C 
//题意:求有多少个子序列(连续的),使得这些子序列中,没有和为 0 的子序列
//思路: l-r 的和为 0 ,转换为 sum[l-1]=sum[r] ,也就是前缀和
//尺取法,每次将 r 向右移动一位,然后根据条件把 l 右移直到符合要求
//在这里,能用尺取法的原因是,如果区间 l-r 中,因为 sum[l] 的原因导致不合法,那么 l 和之前的就都可以不考虑了,对于更大的 r 肯定也不合法 
//此时对答案的贡献是 r-l ,列举一下就能知道 
//原来这么简单比赛的时候就是没想出来 qaq ,当时一直在考虑怎么求不合法情况数,然后再用总数减,死在了去重上 
int main(){
	n=read();
	map[0]=1;
	reg LL ans=0;
	reg int l=0,r=1;
	for(reg int i=1;i<=n;i++) sum[i]=sum[i-1]+read();
	while(r<=n){
		while(map.find(sum[r])!=map.end()&&map[sum[r]]){
			map[sum[l]]=0;l++;
		}
		map[sum[r]]=1;
		ans+=r-l;
		r++;
	}
	std::printf("%lld",ans);
	return 0;
}

 


然而后面的并不想写了qwq

posted @ 2020-04-09 15:50  suxxsfe  阅读(169)  评论(0编辑  收藏  举报