Codeforces Round #531 (Div. 3)

A - Integer Sequence Dividing

没什么意思,不过发现有一个人没开longlong也能过,仔细想了想确实是对的吧。

#include<iostream>
int main() {
    long long n;
    std::cin>>n;
    n*=n+1;
    if(n&3) std::cout<<1;
    else std::cout<<0;
    return 0;
}

B - Array K-Coloring

注意每种颜色都至少出现一次。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cctype>
#define qmin(x,y) (x=min(x,y))
#define qmax(x,y) (x=max(x,y))
using namespace std;

inline char gc() {
//	static char buf[100000],*p1,*p2;
//	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
	return getchar();
}

template<class T>
int read(T &ans) {
	ans=0;char ch=gc();T f=1;
	while(!isdigit(ch)) {
		if(ch==EOF) return -1;
		if(ch=='-') f=-1;
		ch=gc();
	}
	while(isdigit(ch))
		ans=ans*10+ch-'0',ch=gc();
	ans*=f;return 1;
}

template<class T1,class T2>
int read(T1 &a,T2 &b) {
	return read(a)!=EOF&&read(b)!=EOF?2:EOF;
}

template<class T1,class T2,class T3>
int read(T1 &a,T2 &b,T3 &c) {
	return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
}

typedef long long ll;
const int Maxn=5100;
const int inf=0x3f3f3f3f;

int n,k,a[Maxn],bj[Maxn],cnt[Maxn];

signed main() {
//	freopen("test.in","r",stdin);
	read(n,k);
	for(int i=1;i<=n;i++) read(a[i]);
	for(int i=1;i<=k;i++) {
		memset(bj,0,sizeof(bj));
		for(int j=1;j<=n;j++) if(!bj[a[j]]&&a[j]>0)
			bj[a[j]]=1,a[j]=-i,cnt[i]++;
	}
	for(int i=1;i<=n;i++)
		if(a[i]>0) return 0*puts("NO");
	for(int i=1;i<=k;i++) if(!cnt[i])
		for(int j=1;j<=n;j++)
			if(cnt[-a[j]]>1) {cnt[-a[j]]--,a[j]=-i,cnt[i]++; break;}
	puts("YES");
	for(int i=1;i<=n;i++) printf("%d ",-a[i]);
	return 0;
}

C - Doors Breaking and Repairing

首先如果打的比修的快,那肯定全都没有了。

否则只能摧毁一次能打掉的,而在打掉这个的时候,另一个人肯定会修一个能被一次打掉的,那么直接统计能一次打掉的个数除以二再上取整。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cctype>
#define qmin(x,y) (x=min(x,y))
#define qmax(x,y) (x=max(x,y))
using namespace std;

inline char gc() {
//	static char buf[100000],*p1,*p2;
//	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
	return getchar();
}

template<class T>
int read(T &ans) {
	ans=0;char ch=gc();T f=1;
	while(!isdigit(ch)) {
		if(ch==EOF) return -1;
		if(ch=='-') f=-1;
		ch=gc();
	}
	while(isdigit(ch))
		ans=ans*10+ch-'0',ch=gc();
	ans*=f;return 1;
}

template<class T1,class T2>
int read(T1 &a,T2 &b) {
	return read(a)!=EOF&&read(b)!=EOF?2:EOF;
}

template<class T1,class T2,class T3>
int read(T1 &a,T2 &b,T3 &c) {
	return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
}

typedef long long ll;
const int Maxn=5100;
const int inf=0x3f3f3f3f;

int n,x,y,a;

signed main() {
//	freopen("test.in","r",stdin);
	read(n,x,y);
	if(x>y)
		printf("%d",n);
	else {
		int cnt=0;
		for(int i=1;i<=n;i++) {
			read(a);if(a<=x) cnt++;
		}
		printf("%d",cnt+1>>1);
	}
	return 0;
}

D - Balanced Ternary String

本来想抢D的一血,但是调了半天才过,这时候已经有大约五六个人过了。。

那么题意很简单了,换成0的一定是越靠前越好,2一定是越靠后越好,然后考虑1怎么做。

如果一定要把0换下去的话,那么一定不能把前面的0换下去,那么我们把前面的0打标记即可。

#include<bits/stdc++.h>
using namespace std;

char gc() {
//	static char buf[100000],*p1,*p2;
//	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin))?EOF:*p1++;
	return getchar();
}

template<class T>
int read(T &ans) {
	T f=1;ans=0;
	char ch=gc();
	while(!isdigit(ch)) {
		if(ch==EOF) return EOF;
		if(ch=='-') f=-1;
		ch=gc();
	}
	while(isdigit(ch))
		ans=ans*10+ch-'0',ch=gc();
	ans*=f;return 1;
}

template<class T1,class T2>
int read(T1 &a,T2 &b) {
	return read(a)==EOF?EOF:read(b);
}

template<class T1,class T2,class T3>
int read(T1 &a,T2 &b,T3 &c) {
	return read(a,b)==EOF?EOF:read(c);
}

typedef long long ll;
const int Maxn=1100000;
const int inf=0x3f3f3f3f;
const ll mod=1000000007;

int n,a[Maxn];
char s[Maxn];

int main() {
	scanf("%d",&n);
	scanf("%s",s);
	for(int i=0;i<n;i++) a[s[i]]++;
	int now=0;
	while(a['0']<n/3) {
		while(a[s[now]]<=n/3) now++;
		a['0']++;a[s[now]]--;
		s[now]='0';
	}
	now=0;
	for(int i=0;i<n;i++) if(s[i]=='0'&&now!=n/3) s[i]=0,now++;
	now=0;
	while(a['1']<n/3) {
		while(a[s[now]]<=n/3) now++;
		a['1']++;a[s[now]]--;
		s[now]='1';
	}
	now=n-1;
	while(a['2']<n/3) {
		while(a[s[now]]<=n/3) now--;
		a['2']++;a[s[now]]--;
		s[now]='2';
	}
	for(int i=0;i<n;i++) if(s[i]==0) s[i]='0';
	printf("%s",s);
	return 0;
}

E - Monotonic Renumeration

因为b是单调的,而a中一样的元素在b中一定也是单调的,那么从一个元素在a中首次出现到最后一次出现,这中间的b的值一定是完全相等的,那么我们就可以记每个元素在a中最后一次出现是在哪里,然后从前往后看,如果前面所有的元素在a中最后一次出现的位置在当前枚举的位置之后的话,这个位置就一定只有一次填法,否则可以选择加一或不加,那么把答案乘以2即可。

#include<bits/stdc++.h>
using namespace std;

char gc() {
//	static char buf[100000],*p1,*p2;
//	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin))?EOF:*p1++;
	return getchar();
}

template<class T>
int read(T &ans) {
	T f=1;ans=0;
	char ch=gc();
	while(!isdigit(ch)) {
		if(ch==EOF) return EOF;
		if(ch=='-') f=-1;
		ch=gc();
	}
	while(isdigit(ch))
		ans=ans*10+ch-'0',ch=gc();
	ans*=f;return 1;
}

template<class T1,class T2>
int read(T1 &a,T2 &b) {
	return read(a)==EOF?EOF:read(b);
}

template<class T1,class T2,class T3>
int read(T1 &a,T2 &b,T3 &c) {
	return read(a,b)==EOF?EOF:read(c);
}

typedef long long ll;
const int Maxn=1100000;
const int inf=0x3f3f3f3f;
const ll mod=998244353;

int n,a[Maxn];
map<int,int> ma,bj;

int main() {
	scanf("%d",&n);
	for(int i=1;i<=n;i++) {
		scanf("%d",&a[i]);
		ma[a[i]]=i;
	}
	int ans=1,temp=1;
	for(int i=1;i<=n;i++)
		if(!bj[a[i]]) {
			if(temp<i) ans<<=1,ans%=mod;
			bj[a[i]]=1;
			temp=max(temp,ma[a[i]]);
		}
	printf("%d",ans);
	return 0;
}

F - Elongated Matrix

可以直接压成f[i][j][k]表示第一个是i,最后一个是j,当前状态是k的最大值,然后直接(O(n^3log n))转移很虚啊,结果竟然A了?还跑的很快?

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cctype>
#define qmin(x,y) (x=min(x,y))
#define qmax(x,y) (x=max(x,y))
using namespace std;

inline char gc() {
//	static char buf[100000],*p1,*p2;
//	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
	return getchar();
}

template<class T>
int read(T &ans) {
	ans=0;char ch=gc();T f=1;
	while(!isdigit(ch)) {
		if(ch==EOF) return -1;
		if(ch=='-') f=-1;
		ch=gc();
	}
	while(isdigit(ch))
		ans=ans*10+ch-'0',ch=gc();
	ans*=f;return 1;
}

template<class T1,class T2>
int read(T1 &a,T2 &b) {
	return read(a)!=EOF&&read(b)!=EOF?2:EOF;
}

template<class T1,class T2,class T3>
int read(T1 &a,T2 &b,T3 &c) {
	return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
}

typedef long long ll;
const int Maxn=110000;
const int inf=0x3f3f3f3f;

int n,m,a[21][Maxn],f[21][21][Maxn],b[21][21];

signed main() {
//	freopen("test.in","r",stdin);
	read(n,m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++) read(a[i][j]);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++) {
			b[i][j]=inf;
			for(int k=1;k<=m;k++)
				qmin(b[i][j],abs(a[i][k]-a[j][k]));
		}
	for(int i=1,zhy=1;i<=n;i++,zhy<<=1)
		f[i][i][zhy]=inf;
	int sxz=(1<<n)-1;
	for(int i=1;i<=n;i++)
		for(int k=1;k<sxz;k++)
			for(int j=1;j<=n;j++)
				if(f[i][j][k])
					for(int l=1,zhy=1;l<=n;l++,zhy<<=1)
						if(!(zhy&k)) qmax(f[i][l][zhy|k],min(f[i][j][k],b[j][l]));
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			for(int k=1;k<m;k++) qmin(f[i][j][sxz],abs(a[j][k]-a[i][k+1]));
	int ans=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++) qmax(ans,f[i][j][sxz]);
	printf("%d",ans);
	return 0;
}


原文地址:https://www.cnblogs.com/shanxieng/p/10248112.html