2024.3.21|华北水利水电大学江淮校区ACM社团训练赛

2024.3.21|华北水利水电大学江淮校区ACM社团训练赛

1.数字拆解
2.矩阵修改
3.因子数
4.回文数
5.中位数

心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。
在这里插入图片描述

数字拆解

题目
小红拿到了一个偶数,她希望你将其切割成尽可能多的偶数。你能帮帮她吗?
输入描述:
一个偶数
1≤x≤105
输出描述:
输出若干行,从小到大输出每个偶数。
示例1
输入
1024
输出
2
4
10
说明
拆分成"10"+“2”+"4"三个偶数。
示例2
输入
999999999999999999999999990
输出
999999999999999999999999990
示例3
输入
202020
输出
0
0
0
2
2
2
注意
自己看数据范围,用string吧孩子,然后还需要一个动态字符串t去切割、连接和存储,判断是不是偶数你就看这个数最末位能不能对2取余等不等于0就完了。对2取余为0的数有0,2,4,6,8。

实践代码:

bool cmp(string a,string b){
    if(a.size()!=b.size()) return a.size()<b.size();
    return a<b;
}
void solve(){
    string s;cin>>s;
    string t;
    vector<string> a;
    for(int i=0;i<s.length();i++){
        t+=s[i];
        int y=s[i]-'0';
        if(y%2==0) {a.push_back(t);t="";}
    }
    sort(a.begin(),a.end(),cmp);
    for(int i=0;i<a.size();i++) cout<<a[i]<<endl;
}

矩阵修改

题目
小红拿到了一个字符矩阵,矩阵中仅包含"red"这三种字符。
小红每次操作可以将任意字符修改为"red"这三种字符中的一种。她希望最终任意两个相邻的字母都不相同。小红想知道,至少需要修改多少个字符?
输入描述:
第一行输入两个正整数n,m,代表矩阵的行数和列数。
接下来的n行,每行输入一个长度为m的、仅由"red"这三种字符组成的字符串。
1≤n≤4
1≤m≤1000
输出描述:
一个整数,代表需要修改的字母数量的最小值。
示例1
输入
2 3
ree
dee
输出
2
说明:
修改为:
red
dre
即可。

注意
三进制状压dp。

实践代码:


因子数

题目
给出一个质数 n,请求出一个质数 m,使得 n+m 不是质数。
其中,质数是指大于 1 的自然数,除了 1 和自身外,不能被其他自然数整除的数。
输入描述:
仅输入一行,包含一个整数 n(2≤n≤2⋅105 ),保证 n 是质数。
输出描述:
仅输出一行。包含一个质数 m(2≤m≤2⋅105 ),表示答案。
如果有多个可行的答案,请输出任意一个。
可以证明,在题目所给条件下一定有解。
示例1
输入
11
输出
3

### 实践代码:
void solve(){
    int x;cin>>x;
    if(x==1) {cout<<0;return;}
    int cnt=0;
    for(int i=2;i<x/i;i++){
        if(x%i==0){
            cnt++;
            while(x%i==0) x/=i;//排除9=3*3这种质因子相同情况
        }
    }
    if(x>1) cnt++;
    cout<<cnt;
}

回文数

如果一段序列区间是回文的,有两种情况:
1.长度为偶数时,证明区间里的数字是一一对应的,即里面的数字0-9中的每个数的数量是偶数个。
2.长度是奇数时,证明除了中间那个数字之外的数字是一一对应的,即对于数字0-9来说里面有且仅有一个数字的数量是奇数,剩下都必须是偶数个。

题目
小红定义一个整数是“好数”,当且仅当该整数通过重排之后可以形成回文数。(可以包含前导零)
现在小红拿到了一个正整数x,小红想截取一段连续区间得到好数,她想知道有多少种不同的方案?
输入描述:
输入一个正整数1≤x≤105
输出描述:
得到“好数”的方案数。
示例1
输入
110
输出
5
说明
长度为 1 的区间,三个都是合法的。
长度为 2 的区间,"11"是合法的,"10"是不合法的。
长度为 3 的区间, "110"是合法的。

实践代码:

map<vector<int>,int> mp;
vector<int> cnt(10,0);//cnt[i] - i(0~9)这个数字出现了几次(这里只需记录奇/偶个) 1-奇数个 0-偶数个
void solve(){
    string s;cin>>s;
    mp[cnt]++;//初始化为0,即0~9的数字都没出现过,都是偶数
    int ans = 0;
    for(int i=0;i<s.length();i++){
        cnt[s[i]-'0']^=1;//开始为0 异或1为1(奇数个) 之后再出现异或1为0(偶数个)
        ans+=mp[cnt];//加上和它完全一样的区间数
        for(int j=0;j<10;j++){
            //统计只有一个数字出现次数不一样的区间
            vector<int> tmp;
            tmp=cnt;
            tmp[j]^=1;
            ans+=mp[tmp];
        }
        mp[cnt]++;//每次结束之后 这个区间数+1
    }

中位数

计算中位数的步骤如下:
首先,将所有数据按照大小顺序排列。
如果数据数量是奇数,那么中位数就是排序后的中间数值
如果数据数量是偶数,那么中位数是排序后中间两个数的平均值

题目
小红拿到了一个数组:a1 ,a2 ,…,an。她定义 f(i) 为,删除第i个元素后,数组的中位数。现在小红想让你求出f(1),f(2)…f(n)的值,你能帮帮她吗?
输入描述:
第一行输入一个正整数n,代表数组的大小。
第二行输入n个正整数ai,代表数组的元素。
2≤n≤105
1≤ai≤109
输出描述:
输出n行,每行输出一个浮点数,第i行代表f(i)的值。保留一位小数。
示例1
输入
4
2 5 8 1
输出
5.0
2.0
2.0
5.0
示例2
输入
3
1 2 3
输出
2.5
2.0
1.5

实践代码:

void solve(){
    int n;cin>>n;
    vector<int> a(n),b(n);
    for(int i=0;i<n;i++) {cin>>a[i];b[i]=a[i];}
    sort(b.begin(),b.end());
        if(n%2==0){//即删一个数后数列个数为奇数情况
            int t1=b[n/2-1],t2=b[n/2];
            for(int i=0;i<n;i++){
                if(a[i]<t2) printf("%.1f\n",t2*1.0);
                else printf("%.1f\n",t1*1.0);
            }
        }
        else{//即删一个数后数列个数为偶数的情况
            int t1=b[n/2-1];int t2=b[n/2];int t3=b[n/2+1];
            for(int i=0;i<n;i++){
                if(a[i]<t2) printf("%.1f\n",(t2+t3)/2.0);
                if(a[i]>t2) printf("%.1f\n",(t1+t2)/2.0);
                else if(a[i]==t2)printf("%.1f\n",(t1+t3)/2.0);
            }
        }
}

心有猛虎,细嗅蔷薇。再见了朋友~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值