算法学习入门---算法题DAY5

1.小红的数字分裂

  1. 关键观察

每次分裂操作 x → a + b,数组的总和是不变的 。最终所有元素都等于同一个值 T,因此:

  • 最终元素个数为 k,那么 sum = k × T
  • 每个原始元素 a_i 必须是 T 的倍数(因为 a_i 要被拆成若干个 T

要让操作次数最少,就要让 k 尽可能小(操作次数 = k - n),等价于让 T 尽可能大。


  1. 核心结论

T 的最大值就是数组所有元素的最大公约数(GCD)

  • 所有 a_i 都是 GCD 的倍数,因此都能被拆成若干个 GCD
  • 设最终元素个数 k = sum / GCD
  • 最少操作次数 = k - n

ac代码:

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

long long gcd(long long a, long long b) {
    while (b) {
        long long temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n;
    cin >> n;
    vector<long long> a(n);
    long long sum = 0;
    long long g = 0;
    
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
        sum += a[i];
        g = gcd(g, a[i]);
    }
    
    long long k = sum / g;
    cout << k - n << endl;
    
    return 0;
}

2.小红的回文子串

错误代码:

cpp 复制代码
#include<iostream>
#define int long long 
using namespace std;

signed main()
{
	string s;cin>>s;
	int n = s.size();
	s = ' ' + s;
	if(n<=2)
	{
		cout<<0;
		return 0;
	}
	int ret = 0,pos = 0,cur = 0,flag = 1;
	for(int l=1,r=3;r<=n;r++)
	{
		//出窗口 
		if(s[r]!=s[r-2]&&pos) 
		{
			while(l!=flag)
			{
				cur--;
				l++;
			}
			l++;cur--;//跳到了上一次转换数字的下一个数字 
			pos = 0;
			r--;//重来一遍 
			continue;
		}
		cur++; 
		if(s[r]!=s[r-2]) 
		{
			flag = r-2;
			pos = 1;
		}
		ret = max(ret,cur);
	}
	cout<<ret;
	return 0;
}
  • 错误原因:例如 axbxa,我的代码会首先将第一个a改为b,所以无法得到正确答案
  • 正确解法:枚举每个位置,并在每个位置枚举26个字母

ac代码:

cpp 复制代码
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main() {
    string s;
    cin >> s;
    int n = s.size();
    if (n <= 2) {
        cout << 0 << endl;
        return 0;
    }

    // 计算原始的长度为3的回文子串数量
    int base = 0;
    for (int i = 0; i + 2 < n; ++i) {
        if (s[i] == s[i + 2]) base++;
    }

    int max_add = 0;
    // 枚举修改每个位置
    for (int i = 0; i < n; ++i) {
        // 原来的字符
        char original = s[i];
        // 枚举修改成任意字符
        for (char c = 'a'; c <= 'z'; ++c) {
            if (c == original) continue; // 不用改
            int add = 0;
            // 包含i的三元组有:(i-2, i), (i-1, i+1), (i, i+2)
            // 注意:中间的(i-1, i+1)不依赖s[i],所以修改s[i]不影响它,不用算
            // 只需要算(i-2, i)和(i, i+2)
            if (i >= 2) {
                if (s[i - 2] == c) add++;
            }
            if (i + 2 < n) {
                if (c == s[i + 2]) add++;
            }
            // 注意:还要减去原来这两个三元组中,原本就是回文的情况
            if (i >= 2 && s[i - 2] == original) add--;
            if (i + 2 < n && original == s[i + 2]) add--;

            max_add = max(max_add, add);
        }
    }

    cout << base + max_add << endl;
    return 0;
}
相关推荐
Cx330❀35 分钟前
【MySQL基础】一文吃透“表的约束”:从 Null/Default 到主外键的终极安全法则
linux·服务器·数据库·c++·mysql·安全
c238561 小时前
第二篇:《测试指挥官:可视化单题自测框架(含 assert 实操)》
java·数据库·c++·算法·安全性测试
辞旧 lekkk1 小时前
【Redis初阶】常见数据类型
开发语言·数据库·c++·redis·学习·缓存·bootstrap
六点_dn2 小时前
Linux学习笔记-printf命令
linux·运维·算法
遥感知识服务3 小时前
Sentinel-1 + DEM + FwDET + 随机森林:从快速水深初估到多因子误差修正
算法·随机森林·sentinel
来一碗刘肉面3 小时前
顺序表与链表的比较
数据结构·算法·链表
alphaTao3 小时前
LeetCode 每日一题 2026/7/13-2026/7/19
算法·leetcode
nnerddboy3 小时前
脑电信号处理实战 03 | 运动想象脑机接口入门:ERD/ERS、CSP 空间滤波与左右拳想象解码
算法·信号处理
持力行3 小时前
C++与Java变量声明、定义及内存分配的核心区别
java·开发语言·c++
QN1幻化引擎4 小时前
Dalin L — 我造了一门支持中文编程的语言,完整移植到 Rust 了
人工智能·算法·机器学习