Codeforces Round #634 (Div. 3) 补题
Posted dinomax
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #634 (Div. 3) 补题相关的知识,希望对你有一定的参考价值。
A. Candies and Two Sisters
签到题,直接输出即可
代码
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c==‘-‘) flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-‘0‘;c=getchar();}p*=flag;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int q;
read(q);
while(q--){
int n;
read(n);
int t=n/2;
cout<<n-t-1<<endl;
}
return 0;
}
B. Construct the String
长度a含有b个不同的字母,只要把前b个字母循环输出就好了,比赛时想麻烦了
代码
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c==‘-‘) flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-‘0‘;c=getchar();}p*=flag;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int q;
read(q);
while(q--){
int n,a,b;
read(n),read(a),read(b);
int k=a/b;
int cnt=0;
bool flag=true;
for(;;){
for(int i=0;i<b;i++){
for(int j=0;j<k;j++){
putchar(‘a‘+i);
if(++cnt==n){
flag=false;
break;
}
}
if(!flag) break;
}
if(!flag) break;
}
putchar(‘
‘);
}
return 0;
}
C. Two Teams Composing
统计出每种元素的个数,并记录所有元素中的最大个数。如果个数最多的元素为x,那么两个队列有两种构造方式:第一队不包含x,第二队全为x;第一队包含x,第二队全为x,比较这两种构造方式的结果的最大值即可。
代码
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c==‘-‘) flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-‘0‘;c=getchar();}p*=flag;
}
map<int,int> a;
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int q;
read(q);
while(q--){
int n;
int m=0;
int sum=0;
read(n);
//map<int,int> a;
a.clear();
for(int i=0;i<n;i++){
int t;
read(t);
if(!a[t]) sum++;
a[t]++;
m=max(m,a[t]);
}
cout<<max(min(sum-1,m),min(sum,m-1))<<"
";
}
return 0;
}
D. Anti-Sudoku
我的想法是九个小的格子中每个格子一定要改变一个数,让改变的数可以影响一行一列,最后让九个数影响的行和列不同就行了。对于不同的数独,改变的位置可以是固定的,改变的方法可以是让这个数加一。
答案给的方法很巧妙,让数独中所有的某个数变成其他数就好了,比如所有2都变成1
代码
#define LOCAL0
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c==‘-‘) flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-‘0‘;c=getchar();}p*=flag;
}
vector<vector<int> > a(10,vector<int>(10));
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int q;
read(q);
while(q--){
char s;
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++){
cin>>s;
a[i][j]=s-‘1‘;
}
a[1][1]=(a[1][1]+1)%9;
a[2][5]=(a[2][5]+1)%9;
a[3][9]=(a[3][9]+1)%9;
a[5][2]=(a[5][2]+1)%9;
a[6][6]=(a[6][6]+1)%9;
a[4][7]=(a[4][7]+1)%9;
a[9][3]=(a[9][3]+1)%9;
a[7][4]=(a[7][4]+1)%9;
a[8][8]=(a[8][8]+1)%9;
for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++)
printf("%d",a[i][j]+1);
putchar(‘
‘);
}
}
return 0;
}
E1. Three Blocks Palindrome (easy version)
比赛时只想到了E1的解法,还交了八次才过。。。
我的想法是对每一种元素都维护一次前缀和(个数),这样就能方便的得出每种元素在某一区间内的数量。题目要求的数列是分为三部分,我的做法是固定中间的那部分,再遍历两边元素的最大数目,因为是固定中间部分的左边界l和右边界r,遍历l和r的复杂度是n2。
代码
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<stdio.h>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c==‘-‘) flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-‘0‘;c=getchar();}p*=flag;
}
//map<int,int> idx;
int sum[30][3000];
int idx[300];
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int q;
read(q);
while(q--){
int n,cnt=0,ans=0;
read(n);
memset(idx,0,sizeof(idx));
memset(sum,0,sizeof(sum));
for(int i=1;i<=n;i++){
int v;
read(v);
if(!idx[v]) idx[v]=++cnt;
for(int j=1;j<=cnt;j++){
sum[j][i]=sum[j][i-1];
if(idx[v]==j) sum[j][i]++;
}
}
for(int l=1;l<=n;l++)
for(int r=l;r<=n;r++){
for(int i=1;i<=cnt;i++)
for(int j=1;j<=cnt;j++){
//if(l!=1&&j==i) continue;
ans=max(ans,sum[i][r]-sum[i][l-1]+2*min(sum[j][n]-sum[j][r],sum[j][l-1]));
//cout<<l<<" "<<r<<" "<<ans<<endl;
}
}
for(int i=1;i<=cnt;i++) ans=max(ans,sum[cnt][n]);
cout<<ans<<"
";
}
return 0;
}
E2. Three Blocks Palindrome (hard version)
其实标程前半部分也是维护前缀数目,但是后面在求解的时候是相当于固定两边,遍历中间的部分,预处理时要统计每种元素出现的位置。求解时按照元素遍历,先统计这种元素在[1,n]上的数目,再把这种元素左右各取c个,就可以得到中间部分左右端的位置。
代码
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<stdio.h>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c==‘-‘) flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-‘0‘;c=getchar();}p*=flag;
}
int sum[30][3000];
int idx[300];
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int q;
read(q);
while(q--){
int n;
read(n);
vector<int> a(n+1);
vector<vector<int> > pref(201,vector<int>(n+1));
vector<vector<int> > pos(201);
for(int i=1;i<=n;i++) read(a[i]);
for(int i=1;i<=n;i++){
for(int j=1;j<=200;j++) pref[j][i]=pref[j][i-1];
pref[a[i]][i]++;
pos[a[i]].push_back(i);
}
int ans=0;
for(int i=1;i<=200;i++){
int u=pos[i].size();
ans=max(ans,u);
for(int j=1;2*j<=u;j++){
int l=pos[i][j-1];
int r=pos[i][u-j];
for(int k=1;k<=200;k++){
if(k==i) continue;
ans=max(ans,2*j+pref[k][r-1]-pref[k][l]);
}
}
}
cout<<ans<<"
";
}
return 0;
}
F. Robots on a Grid
首先所给图中是由一些环组成的,否则机器人会一直走到没走过的点,而图的大小是有限的。如果两个机器人在某一时刻相遇,那么他们之后会一起走,就是题中的不允许的条件,因为环的最大周期不超过n*m,所以只要两个机器人在n*m步内没有相遇,那么他们就不可能相遇。统计每个格子上的机器人n*m步之后会在哪,之后就能得到n*m步之后有几个格子上的机器人能走到某一格,以及几个黑格子上的机器人能走到某个黑格子,就能方便的统计答案,让每个格子上的机器人走n*m步显然会超时,所以采用倍增的方法。
代码
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<stdio.h>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c==‘-‘) flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-‘0‘;c=getchar();}p*=flag;
}
int sum[30][3000];
int idx[300];
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int q;
read(q);
while(q--){
int n,m;
read(n),read(m);
vector<int> col(n*m),dp(n*m),dpn(n*m),ans(n*m),co(n*m);
string s;
for(int i=0;i<n;i++){
cin>>s;
for(int j=0;j<m;j++){
col[i*m+j]=(s[j]==‘0‘);
}
}
for(int i=0;i<n;i++){
cin>>s;
for(int j=0;j<m;j++){
int nxt=-1;
if(s[j]==‘U‘) nxt=(i-1)*m+j;
if(s[j]==‘D‘) nxt=(i+1)*m+j;
if(s[j]==‘L‘) nxt=i*m+j-1;
if(s[j]==‘R‘) nxt=i*m+j+1;
dp[i*m+j]=nxt;
}
}
int k=0;
n*=m;
while((1<<k)<=n) k++;
while(k--){
for(int i=0;i<n;i++){
dpn[i]=dp[dp[i]];
}
for(int i=0;i<n;i++){
dp[i]=dpn[i];
}
}
for(int i=0;i<n;i++){
ans[dp[i]]++;
co[dp[i]]+=col[i];
}
int res=0,_res=0;
for(int i=0;i<n;i++){
if(ans[i]) res++;
if(co[i]) _res++;
}
cout<<res<<" "<<_res<<"
";
}
return 0;
}
以上是关于Codeforces Round #634 (Div. 3) 补题的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #634 (Div. 3)
Codeforces Round #634 (Div. 3)
Codeforces Round #634 D. Anti-Sudoku(构造/水)
Codeforces Round #436 E. Fire(背包dp+输出路径)