Codeforces Round #634 (Div.3)

Codeforces Round #634 Div.3

A

题意:给两姐妹分糖,需要Alice的糖比Betty的糖多,问有多少种分法(所有糖必须分完)。

题记:两种情况,糖的数量少于3时没有一种分法符合条件,糖大于三的情况直接输出(n-1)/2即可。

#include<iostream>

using namespace std;

int main(){
    int t;
    cin>>t;
    while(t--){
        int x;
        cin>>x;
        if(x<3)cout<<0<<endl;
        else cout<<(x-1)/2<<endl;
    }
    return 0;
}

B

题意:构造一个长度为n的的字符串,每个长度为a的字串都有b个不同的字母。

题记:循环输出b个不同字母即可

例如:abcabcabc

#include<iostream>

using namespace std;
char str[]={"abcdefghijklnmopqrstuvwxyz"};
int main(){
    int t;
    cin>>t;
    while(t--){
        int n,a,b;
        cin>>n>>a>>b;
        int sum=0;
        for(int i=0;i<n;i++){
            cout<<str[i%b];
        }
        cout<<endl;
    }
    return 0;
}

C

题意:把学生分两组,第一组全部学生的数值都要不同,第二组所有学生的数值都要相同。两组学生数量相同,求出组中学生数量的最大值。

题记:把相同数值的学生的最大数量(sum2)和不同学生数值的最大数量(sum1)记录下来,然后分情况讨论。

1、如果sum1=sum2,由于sum1中是包含了一个sum2的,所以答案要取sum1-1。

2、如果sum1>sum2,取sum2为答案。

3、如果sum2>sum1,取sum1为答案。

4、如果sum2为0,sum1不为大于1则答案取1,否则取0。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=2e5+10;
int a[N];
int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int sum1=0,sum2=0,x;
        memset(a,0,sizeof(a));
        for(int i=0;i<n;i++){
            cin>>x;
            a[x]++;
            if(a[x]==1) sum1++;
            else if(a[x]>1) sum2=max(sum2,a[x]);
        }
        int ans=0;
        if(n==1) ans=0;
        else if(sum1>1&&sum2==0) ans=1;
        else if(sum1>sum2) ans=sum2;
        else if(sum1==sum2) ans=sum1-1;
        else if(sum1<sum2) ans=sum1;
        cout<<ans<<endl;
    }
    return 0;
}

D

题意:给出一个9x9的数独方阵,需要输出一个反数独,即每一行每一列每一个3x3方格(题目有画出来)都要有相同的数字。

题记:只需要找出9个不同行不同列不同3x3方格的数改变它们的数值即可。例如第一个代码(一开始写的…),但是其实在数独中选一个数,改变它的值就行了。例如把全部的1改成2(第二个代码)。因为在数独的方阵中同一个数就是在不同行不同列不同3x3方阵中。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=2e5+10;
char a[11][11];
int main(){
    int t;
    cin>>t;
    while(t--){
        for(int i=1;i<=9;i++)
            for(int j=1;j<=9;j++)
                cin>>a[i][j];
        for(int i=1,j=1;i<=9;i+=3,j++){
            //cout<<i<<j<<i<<j+3<<i<<j+6<<endl;
            if(a[i][j]!='1')a[i][j]='1';
            else a[i][j]='2';
            if(a[i+1][j+3]!='1')a[i+1][j+3]='1';
            else a[i+1][j+3]='2';
            if(a[i+2][j+6]!='1')a[i+2][j+6]='1';
            else a[i+2][j+6]='2';
            //out<<a[i][j]<<a[i][j+3]<<a[i][j+6];
        }
        for(int i=1;i<=9;i++){
            for(int j=1;j<=9;j++){
                cout<<a[i][j];
            }
            cout<<endl;
        }
    }
    return 0;
}
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=2e5+10;
char a[11][11];
int main(){
    int t;
    cin>>t;
    while(t--){
        for(int i=1;i<=9;i++)
            for(int j=1;j<=9;j++)
                cin>>a[i][j];
        for(int i=1;i<=9;i++){
            for(int j=1;j<=9;j++){
                if(a[i][j]=='1') cout<<'2';
                else cout<<a[i][j];
            }
            cout<<endl;
        }
    }
    return 0;
}

E

参考了大佬的代码:https://www.cnblogs.com/heyuhhh/p/12699998.html
题意:找出符合题目的最长子序列,输出最长的长度。

#include<iostream>
#include<vector>
using namespace std;
const int N=2e5+10,M=205;
int a[N],f[N][M];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t; cin>>t;
    while(t--){
        int n;
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        vector<vector<int>> at(M);
        //建一个二维vector,初始化值为205
        for(int j=1;j<=200;j++){
            for(int i=1;i<=n;i++){
                f[i][j]=f[i-1][j]+(a[i]==j);
                //cout<<i<<' '<<j<<' '<<f[i][j]<<endl;
                //表示开始到第i个位置j数字的个数
                if(a[i]==j){
                    //cout<<i<<' '<<j<<endl;
                    at[j].push_back(i);
                    //从1到200把数的下标存下来
                }
            }
        }
        int ans=0;
        for(int i=1;i<=200;i++){
            //从1到两百遍历一遍
            for(int l=0;l<at[i].size();l++){
                int r=(int)at[i].size()-1-l;//右端点
                if(l>r)break;//当l>r时退出循环
                if(l==r) ans=max(ans,(int)at[i].size());
                //当左端点和右端点重合时
                else{
                    int mmax=0;
                    for(int j=1;j<=200;j++){
                        mmax = max(mmax, f[at[i][r] - 1][j] - f[at[i][l]][j]);
                    }
                    ans=max(ans,2*(l+1)+mmax);
                }
            }
        }
        cout<<ans<<'\n';
    }
    return 0;
}

F

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值