牛牛看云(贪心,哈希,推公式)- 牛客寒假训练营第一场

原题链接

题目

在这里插入图片描述

思路

  1. 本题最重要的一点在于要注意观察到数据范围,说明肯定有数是重复出现多次的
  2. 考虑哈希,记录每个数出现的次数
  3. 对于两个不同数,他们根据题目要求总共可以组成 c n t a ∗ c n t b cnt_a * cnt_b cntacntb 个相同组合
  4. 对于两个相同数,他们根据题目要求总共可以组成 ( 1 + c n t a ) ∗ c n t a / 2 (1 + cnt_a) * cnt_a / 2 (1+cnta)cnta/2 个相同组合【参考那个首相加末项的公式】。
  5. 注意开 l o n g l o n g longlong longlong

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
	int n;
	cin >> n;
	map<int, int> ma;
	for (int i = 1; i <= n; i ++ )
	{
		int x;
		cin >> x;
		ma[x] ++;
	}
	int sum = 0;
	for (int i = 0; i <= 1000; i ++ )
	{
		for (int j = i; j <= 1000; j ++ ) 
		{
			int add;
			if (i == j) add = (1 + ma[i]) * ma[i] / 2;
			else add = ma[i] * ma[j];
			sum += abs(i + j - 1000) * add;
		}
	}
	cout << sum << endl;
	return 0;
}

总结

赛时其实想到了数据范围,可是接着就想到了用set做,总之就是再瞎绕弯子,赛时还是需要注意心态的,否则简单的题目都做不出来。

贴一个赛时错误代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
    set<int> s;
    unordered_map<int, int> ma;
    int n;
    cin >> n;
    for (int i = 1; i <= n; i ++ )
    {
        int x;
        cin >> x;
        ma[x] ++;
        s.insert(x);
    }
    int sum = 0;
    for (auto i : s)
    {
        for (int j : s)
        {
            if (i == j)
            {
                sum = sum + abs(i + j - 1000) * (ma[i] * (ma[i] - 1));
            }
            else
            {
                sum = sum + abs(i + j - 1000) * (ma[i] * ma[j] );
            }
        }
    }
    cout << sum << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值