题解 | #强迫症#

强迫症

https://ac.nowcoder.com/acm/problem/16301

考虑这个操作的本质,就是任意选一组 i,ji,j,令 aiai+aja_i\leftarrow a_i+a_j

那么一次至多消除一个重复的数字,所以最优的次数就是重复数字的个数。(例如 1 1 1 11~1~1~1 就认为有 33 次重复,2 2 22~2~2 就认为有 22 次重复)

考虑证明这个解存在:

把原序列排序,把重复的数字标记出来,然后从后往前做一波 +=+= 的操作就可以了:

例如:

1 1 1 2 2 2 3 3 31 ~ \color{red}1 ~ 1\color{black} ~ 2 ~ \color{red}2 ~ 2 \color{black}~ 3 ~ \color{red}3 ~ 3

我们直接对红色这些数字进行:

for (int j = len - 1; j >= 1; --j)
  	b[j] += b[j + 1];

的操作,即可把原序列变成:

1 12 11 2 10 8 3 6 31 ~ \color{red}12 ~ 11\color{black} ~ 2 ~ \color{red}10 ~ 8 \color{black}~ 3 ~ \color{red}6 ~ 3

肉眼可见这种方法一定是对的。(注意一开始的那一个还要加回来一个最大的 1212

#include<cstdio>
#include<algorithm>
int init(){
	char c = getchar();
	int x = 0, f = 1;
	for (; c < '0' || c > '9'; c = getchar())
		if (c == '-') f = -1;
	for (; c >= '0' && c <= '9'; c = getchar())
		x = (x << 1) + (x << 3) + (c ^ 48);
	return x * f;
}
void print(int x){
	if (x < 0) x = -x, putchar('-');
	if (x > 9) print(x / 10);
	putchar(x % 10 + '0');
}
const int N = (int) 1e5 + 5;
int a[N];
int main(){
    int n = init();
    for (int i = 1; i <= n; ++i)
        a[i] = init();
    std::stable_sort(a + 1, a + 1 + n);
    int tot = 0;
    for (int i = 1; i <= n; ++i)
        if (a[i] == a[i - 1]) ++tot;
    print(tot), putchar('\n');
}
全部评论

相关推荐

HR_丸山彩同学:你的项目描述里,系统设计讲了很多:MemCube是什么、三级存储架构怎么设计、四种遗忘策略分别是什么。这些面试的时候讲没问题,但简历上不需要这么细。 简历要突出的是影响力,不是实现细节。面试官看简历的时候想知道的是「这个项目有多大价值」,不是「这个项目具体怎么实现的」。实现细节是面试时候聊的 怎么改:技术细节可以精简为一句「采用三级存储架构+四种遗忘策略」,把省出来的篇幅用来写影响力。比如:项目有没有开源?有没有写成技术博客?有没有被别人使用过? 校园经历没有任何信息量,任何人都可以写这句话,写了等于没写。更关键的是,你投的是技术岗,校园活动经历本来就不是加分项。如果非要写,必须写出具体的数字和成果。如果你没有这些数字,那就老老实实删掉 「端到端耗时缩减30-40%」要给出确切数字和绝对值。从1000ms降到600ms是降了40%,从100ms降到60ms也是降了40%,但这两个含义完全不一样。其他也是,涉及到数据,准备好证据,口径统一,面试会问 「熟练」「熟悉」「了解」混在一起用,读起来很乱。而且「了解前端需求」最好改成「具备前后端协作经验」
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务