Codeforces Round #634 (Div. 3)

Solutions


A. Candies and Two Sisters

直接\(\frac{x-1}2\)

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define sz(x) ((int)(x).size())
typedef vector<int> VI;
typedef pair<int,int> PII;
const int N=100010;
const int inf=0X3f3f3f3f;
const long long INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-6;
const double pi=acos(-1.0);
const int mod=1000000007;
typedef long long ll;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
// head
int _;
int main() {
	for (scanf("%d",&_);_;_--) {
		ll x;
		scanf("%lld",&x);
		if (x&1) printf("%lld\n",x/2);
		else printf("%lld\n",max(1ll*0,x/2-1));
	}	
}

B. Construct the String

发现和字串长度无关,直接循环不同字符数即可。这样肯定是符合的。

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define sz(x) ((int)(x).size())
typedef vector<int> VI;
typedef pair<int,int> PII;
const int N=100010;
const int inf=0X3f3f3f3f;
const long long INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-6;
const double pi=acos(-1.0);
const int mod=1000000007;
typedef long long ll;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
// head
int _;
string s;
int len,cur;
int main() {
	for (scanf("%d",&_);_;_--) {
		int n,a,b;
		scanf("%d%d%d",&n,&a,&b);
		s.clear();
		len=0;cur=0;
		while (len<n) {
			s+='a'+cur;
			cur++;
			if (cur==b) cur=0;
			len++;
		}
		cout<<s<<'\n';
	}
}

C. Two Teams Composing

贪心的想,肯定是出现次数最多的在一边,然后不考虑这个数,看不同的数有多少,取最小值。还要考虑是否能让过去一个。

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define sz(x) ((int)(x).size())
typedef vector<int> VI;
typedef pair<int,int> PII;
const int N=100010;
const int inf=0X3f3f3f3f;
const long long INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-6;
const double pi=acos(-1.0);
const int mod=1000000007;
typedef long long ll;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
// head
int _;
int n;
int num[2*N];
int main() {
	for (scanf("%d",&_);_;_--) {
		scanf("%d",&n);
		VI t(n);
		for (int i=0;i<n;i++) {
			scanf("%d",&t[i]);
			num[i+1]=0;
		}
		for (auto it:t) {
			num[it]++;
		}
		int maxx=0,pos=-1;
		for (int i=1;i<=n;i++) {
			if (num[i]>maxx) {
				pos=i;
				maxx=num[i];
			}
		}
		int cnt=0;
		for (int i=1;i<=n;i++) {
			if (num[i]&&i!=pos) cnt++;
		}
		if (cnt+1<num[pos]) cnt++;
		printf("%d\n",min(cnt,num[pos]));
	}
}

D. Anti-Sudoku

感觉这个题应该放到B题emmmmm,随便将一个字符改成非本身即可,比如把2都改为1

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define sz(x) ((int)(x).size())
typedef vector<int> VI;
typedef pair<int,int> PII;
const int N=100010;
const int inf=0X3f3f3f3f;
const long long INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-6;
const double pi=acos(-1.0);
const int mod=1000000007;
typedef long long ll;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
// head
int _;
int main() {
	for (scanf("%d",&_);_;_--) {
		string s;
		for (int i=0;i<9;i++) {
			cin>>s;
			for (int j=0;s[j];j++) {
				if (s[j]=='2') s[j]='1';
			}
			cout<<s<<'\n';
		}
	}
}

E1. Three Blocks Palindrome (easy version)

这个题和某个位置左右两边的数出现次数有关,所以我们可以\(cnt[i][j]\),表示\(i\)前面\(j\)出现的次数,然后前缀和思想可以求得\([l,r]\)之间某数字出现的次数,那么我们可以暴力两端点求解。

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define sz(x) ((int)(x).size())
typedef vector<int> VI;
typedef pair<int,int> PII;
const int N=100010;
const int inf=0X3f3f3f3f;
const long long INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-6;
const double pi=acos(-1.0);
const int mod=1000000007;
typedef long long ll;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
// head
int _;
int cnt[2010][26];
int main() {
	for (scanf("%d",&_);_;_--) {
		int n;
		scanf("%d",&n);
		VI a(n);
		for (int i=0;i<n;i++) scanf("%d",&a[i]);
		for (int i=0;i<n;i++) {
			for (int j=0;j<26;j++) cnt[i+1][j]=cnt[i][j];
			cnt[i+1][a[i]-1]++;
		}
		int ans=0;
		for (int i=0;i<26;i++) ans=max(ans,cnt[n][i]);
		for (int i=0;i<n;i++) {
			for (int j=i;j<n;j++) {
				int cntin=0,cntout=0;
				for (int k=0;k<26;k++) {
					cntin=max(cntin,cnt[j+1][k]-cnt[i][k]);
					cntout=max(cntout,min(cnt[i][k],cnt[n][k]-cnt[j+1][k]));
				}
				ans=max(ans,cntin+cntout*2);
			}
		}
		printf("%d\n",ans);
	}	
}

E2. Three Blocks Palindrome (hard version)

这个时候不能暴力求了,不过我们还可以用\(cnt[i][j]\)的思想。定义\(pos[i]\)存放数字\(i\)出现的位置,我们可以遍历每一个数字的\(pos[i]\),然后跑位置的左半部分,根据这个来划分\([l,r]\),这样第一块和第三块就直接求解了。然后第二块是\(cnt[r+1][k]-cnt[l][k]\)的最大值。

这个复杂度是\(O(nk)\)的,外面两层就是\(n\)的大小,然后每个跑\(k\)

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define sz(x) ((int)(x).size())
typedef vector<int> VI;
typedef pair<int,int> PII;
const int N=100010;
const int inf=0X3f3f3f3f;
const long long INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-6;
const double pi=acos(-1.0);
const int mod=1000000007;
typedef long long ll;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
// head
int _;
//int cnt[2*N][210];
//vector<int> pos[210];
int main() {
	for (scanf("%d",&_);_;_--) {
		int n;
		scanf("%d",&n);
		VI a(n);
		vector<vector<int> > cnt(n+1,vector<int>(210));
		vector<vector<int> > pos(210);
		for (int i=0;i<n;i++) scanf("%d",&a[i]);
		for (int i=0;i<n;i++) {
			for (int j=0;j<210;j++) cnt[i+1][j]=cnt[i][j];
			cnt[i+1][a[i]-1]++;
			pos[a[i]-1].pb(i);
		}
		int ans=0;
		for (int i=0;i<210;i++) {
			ans=max(ans,cnt[n][i]);
			for (int j=0;j<sz(pos[i])/2;j++) {
				int l=pos[i][j]+1,r=pos[i][sz(pos[i])-1-j]-1;
				int sum=0;
				for (int k=0;k<210;k++) sum=max(sum,cnt[r+1][k]-cnt[l][k]);
				//printf("%d***%d    sum:%d\n",l,r,sum);
				ans=max(ans,sum+(j+1)*2);
			}
		}
		printf("%d\n",ans);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值