算法学习入门---算法题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;
}
相关推荐
揽星河..17 分钟前
【C语言】猜数字游戏
c语言·算法·游戏
傲世仙尊39 分钟前
继承-类设计层次复用切片转换与菱形继承的死结
c++
架构师伯子明41 分钟前
FFmpeg C++学习(一):编译和demo
开发语言·c++·学习
LabVIEW开发1 小时前
CTM-3 红外测温仪 + LabVIEW 温度怎么测?
算法·labview·测试·labview程序
纪念 2291 小时前
C++算法(六)
开发语言·c++·算法
ShineWinsu2 小时前
对于Qt:QCheckBox常见属性的详细解析
c++·qt·面试·笔试·gui·qcheckbox·多选框
Dumbness2 小时前
UIA 读微信群消息没有 id,怎么判断哪条是新的:后缀对齐在翻历史和撤回时整屏重报
python·算法
taka2 小时前
从 24x 到 141x:我用纯 Python 零依赖项目,扒开了 GPU 加速的性能黑洞
算法
AI的探索之旅2 小时前
97 个 OpenCV 实例(三十七):二维码识别,一张图四个码的陷阱
c++·opencv·计算机视觉
UIU1143 小时前
P16237 [蓝桥杯 2026 省 B] 应急布线
数据结构·c++·算法·蓝桥杯