专栏文章
B4174 厂房 题解
B4174题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miolc8g4
- 此快照首次捕获于
- 2025/12/02 21:05 3 个月前
- 此快照最后确认于
- 2025/12/02 21:05 3 个月前
B4174 厂房
思路分析
Ciallo~(∠・ω< )⌒★
这是一道很简单的贪心题,由于只需求分的最小组数,所以可以无脑分给左边,越长越好。
那么该如何判断当前的数能否分给左边呢?
在一个公差大于 等差数列中, 个个数之差的最小公倍数应大于 ,因此只需抓住这个点,并且额外注意每组中绝对不能出现相同数字。
具体细节代码解释。
那么该如何判断当前的数能否分给左边呢?
在一个公差大于 等差数列中, 个个数之差的最小公倍数应大于 ,因此只需抓住这个点,并且额外注意每组中绝对不能出现相同数字。
代码
CPP#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 10;
int n, ans, a[N];
unordered_map <int, int> m; //使用 unordered_map 统计数字是否出现,比set更简单
void solve() {
int gcd = 0, dif; //dif为两数差值
m[a[1]] += 1;
for(int i = 2; i <= n; i++) {
dif = abs(a[i] - a[i-1]);
if(m[a[i]] || __gcd(gcd, dif) <= 1) {
ans ++, gcd = 0;
m.clear(); //清空map
m[a[i]] += 1; //一定要加,这是下一组的第一个数
} else {
gcd = __gcd(gcd, dif);
m[a[i]] += 1;
}
}
ans += 1; //最后一组无法在循环中被判断,因此补上一组
return ;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
solve();
cout << ans << '\n';
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...