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);
}
}
埋骨何须桑梓地,人生无处不青山