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^3\log 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;
}