A - Candies and Two Sisters
题意:
有n颗糖,姐姐和妹妹分,姐姐必须比妹妹的少,问有几种情况,必须每人有一颗。
思路:
答案就是(n-1)/2
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define il inline
#define it register int
#define inf 0x3f3f3f3f
#define lowbit(x) (x)&(-x)
#define pii pair<int,int>
#define mak(n,m) make_pair(n,m)
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
const int maxn=1e6+10;
const int mo=1e9;
ll ksm(ll a,ll b){if(b<0)return 0;ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;}
int t;
int n,m;
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
if(n<3){printf("0
");}
else{
printf("%d
",(n-1)/2);
}
}
return 0;
}
B - Construct the String
题意:
有n,a,b,长度是n的字符串,每a个字符串,都有b个不同字母,进行构造,输出其中一个。
思路:
先构造s一个a长度,前b项全不同,b项之后跟b一样,然后a项之后开始循环构造的s
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define il inline
#define it register int
#define inf 0x3f3f3f3f
#define lowbit(x) (x)&(-x)
#define pii pair<int,int>
#define mak(n,m) make_pair(n,m)
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
const int maxn=2e3+10;
const int mo=1e9;
ll ksm(ll a,ll b){if(b<0)return 0;ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;}
int t;
int n,a,b;
char s[maxn];
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&n,&a,&b);
int c=0,bb=b-1;
for(it i=0;i<a;i++){
s[i]='a'+bb;
if(bb!=0){
bb--;
}
}
for(it i=0;i<n;i++){
printf("%c",s[i%a]);
}
printf("
");
}
return 0;
}
C - Two Teams Composing
题意:
有n人,ai代表技能,n个人要分成两个相同数量的组合,第一个组合技能ai值都不同,第二个组合技能ai值都相同,问最大的相同数量是多少。
思路:
把出现1次的ai统计(ans),把出现重复的ai,个数统计(ge),最大量统计(maxx),答案就是max(min(ans+ge,maxx-1),min(ans+ge-1,maxx));
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define il inline
#define it register int
#define inf 0x3f3f3f3f
#define lowbit(x) (x)&(-x)
#define pii pair<int,int>
#define mak(n,m) make_pair(n,m)
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
const int maxn=2e5+10;
const int mo=1e9;
ll ksm(ll a,ll b){if(b<0)return 0;ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;}
int t;
int n;
int a[maxn],cnt[maxn];
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
map<int,int>mp;int ge=0;
for(it i=0;i<n;i++){
scanf("%d",&a[i]);
if(mp[a[i]]==0){
mp[a[i]]=++ge;
cnt[ge]=1;
}
else{
cnt[mp[a[i]]]++;
}
}
int ans=0,maxx=0,g1=0;
for(it i=1;i<=ge;i++){
if(cnt[i]==1){ans++;}
else{g1++;}
maxx=max(cnt[i],maxx);
}
int sheng=g1+ans;
printf("%d
",max(min(g1+ans,maxx-1),min(g1+ans-1,maxx)));
}
return 0;
}
D - Anti-Sudoku
题意:
给9 * 9的数独,要求变成各行各列,每3*3的格子出现2个相同数。
思路:
把1变成2就可以了。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define il inline
#define it register int
#define inf 0x3f3f3f3f
#define lowbit(x) (x)&(-x)
#define pii pair<int,int>
#define mak(n,m) make_pair(n,m)
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
const int maxn=2e5+10;
const int mo=1e9;
ll ksm(ll a,ll b){if(b<0)return 0;ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;}
int t;
int n;
char s[10][10];
int main(){
scanf("%d",&t);
while(t--){
for(it i=0;i<9;i++){
scanf("%s",s[i]);//printf("
%s
",s[i]);
}
for(it i=0;i<9;i++){
for(it j=0;j<9;j++){
if(s[i][j]=='1'){
s[i][j]='2';
}//cout<<s[i][j]<<endl;
}
}
for(it i=0;i<9;i++){
printf("%s
",s[i]);
}
}
return 0;
}
E1 - Three Blocks Palindrome (easy version)
题意:
Let's define a three blocks palindrome as the sequence, consisting of at most two distinct elements (let these elements are a and b, a can be equal b) and is as follows: [a,a,…,a【x】,b,b,…,b【y】,a,a,…,a【x】]. There x,y are integers greater than or equal to 0. For example, sequences [], [2], [1,1], [1,2,1], [1,2,2,1] and [1,1,2,1,1] are three block palindromes but [1,2,3,2,1], [1,2,1,2,1] and [1,2] are not.
Your task is to choose the maximum by length subsequence of a that is a three blocks palindrome.
给n长度数组ai,ai<27,n<=2000
思路:
暴力啊,把每个ai位置存下来,然后进行判断,具体操作看代码吧,因为 E2我tle在10的样例,所以不是正确的解答思路。待补E2,F
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define il inline
#define it register int
#define inf 0x3f3f3f3f
#define lowbit(x) (x)&(-x)
#define pii pair<int,int>
#define mak(n,m) make_pair(n,m)
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
const int maxn=2e3+10;
const int mo=1e9;
ll ksm(ll a,ll b){if(b<0)return 0;ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;}
int t,n,a;
int cnt[27][maxn];
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(it i=0;i<=26;i++){cnt[i][0]=0;}
for(it i=1;i<=n;i++){
scanf("%d",&a);
cnt[a][0]++;cnt[a][cnt[a][0]]=i;
}
int maxx=0;
for(it i=1;i<=26;i++){
maxx=max(cnt[i][0],maxx);
}
for(it i=1;i<=26;i++){
for(it j=1;j<=26;j++){
if(j==i || cnt[i][0]==0 || cnt[j][0]==0){continue;}
int ans=0;
for(it ii=1;ii<=cnt[i][0]/2;ii++){
ans=ii*2;int l=cnt[i][ii],r=cnt[i][cnt[i][0]-ii+1],l1=0,r1=0;
// cout<<l<<" "<<r<<endl;
for(it jj=1;jj<=cnt[j][0];jj++){
if(l<cnt[j][jj]){l1=jj;break;}
}
for(it jj=cnt[j][0];jj>=1;jj--){
if(r>cnt[j][jj]){r1=jj;break;}
}
//cout<<i<<" "<<j<<" "<<r1<<" "<<l1<<" "<<ii<<endl;
if(l1==0 || r1==0 || r1<l1){continue;}
ans+=r1-l1+1;maxx=max(ans,maxx);
}
}
}
printf("%d
",maxx);
}
return 0;
}
upd:E2其实就是我的E1代码填一个前缀和,省去了一遍遍for(1,cnt[i][0])去找中间有多少个数。
E2 - Three Blocks Palindrome (hard version)
E1的题面:修改ai的范围从26变为了200,n的长度从2000变成了2e5
思路:
记录下每个ai的位置,然后在记录一下这个位置上1~200数字的个数前缀和,复杂度o(200 * 200 * 最大ai出现次数/2)
选择1 ~ 200数,个数一定是2以上,要两边相同个数,在选择1 ~ 200的另一个数,问中间最多可能多少.
最奇怪的是我开200*2e5的两个数组,一定算我mle,只好其中一个开了vector才过,不明白为啥会卡mle
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define il inline
#define it register int
#define inf 0x3f3f3f3f
#define lowbit(x) (x)&(-x)
#define pii pair<int,int>
#define mak(n,m) make_pair(n,m)
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
const int maxn=2e5+10;
const int mo=1e9;
ll ksm(ll a,ll b){if(b<0)return 0;ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;}
int t,n,a;
vector<int>cnt[201];
int p[maxn][201];
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(it i=0;i<=200;i++){cnt[i].clear();}
for(it i=0;i<=n;i++){p[i][0]=0;}
for(it i=1;i<=n;i++){
scanf("%d",&a);
cnt[a].push_back(i);
for(it j=1;j<=200;j++){
p[i][j]=p[i-1][j];
}
p[i][a]++;
}
int maxx=0;
for(it i=1;i<=200;i++){
int ss=cnt[i].size();//cout<<ss<<endl;
maxx=max(ss,maxx);
}
for(it i=1;i<=200;i++){
for(it j=1;j<=200;j++){
if(j==i || cnt[i].size()<=1 || cnt[j].size()==0){continue;}
int ans=0;
for(it ii=0;ii<=(cnt[i].size()-1)/2;ii++){
ans=(ii+1)*2;//if(ans+cnt[j][0]<maxx){continue;}
int l=cnt[i][ii],r=cnt[i][cnt[i].size()-ii-1];
if(l==r){break;}
ans+=p[r][j]-p[l][j];//cout<<r<<" "<<l<<" "<<p[r][j]<<" "<<p[l][j]<<endl;
maxx=max(maxx,ans);
}
}
}
printf("%d
",maxx);
}
return 0;
}