算法学习入门---算法题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;
}
相关推荐
San813_LDD2 小时前
[量化]《虚函数调用时间复杂度完全解析:为什么是 O(1) 以及它的真实代价》
java·数据结构·算法
MartinYeung52 小时前
[论文学习]利用索引梯度优化基于优化的 LLM 越狱攻击:MAGIC 方法的深度分析与实现
人工智能·学习·算法
数据仓库搬砖人2 小时前
特征选择三剑客:前向、后向、全子集,哪种更适合你?
算法
牛油果子哥q2 小时前
【C++ this指针】C++ this指针深度精讲:this底层本质、存储位置、调用机制、const this指针、空指针调用、面试坑点与工程实战
开发语言·c++·面试
起个破名想半天了2 小时前
算法与数据结构之Floyd算法
数据结构·算法
千寻girling2 小时前
机器学习 | 无监督学习算法(了解) | 尚硅谷学习
学习·算法·机器学习
小七在进步2 小时前
数据结构:线性表之顺序表
c语言·数据结构·算法
张小九992 小时前
【酶改造】如何利用进化信息快速定位蛋白质突变热点?EVcouplings 保姆级教程
算法
坚果派·白晓明2 小时前
[鸿蒙PC三方库移植适配] 使用 AtomCode + Skills 自动完成spdlog鸿蒙化适配
c++·华为·ai编程·harmonyos·skills·atomcode