1 条题解

  • 0
    @ 2025-11-3 10:27:55

    我叶梓楣也要成为duck大魔王!!!(1)

    这道题这里提供两种做法:

    第一种:

    第一种是找规律 我们通过手模可以发现 考虑最极端的情况 当n==n/2 然后再去想大于和小于

    1.n<=n/2

    如果n为偶数 一个数字出现的最大次数等于n/2,那么答案肯定为0

    如果n为奇数 那么 肯定为1 最后剩下一个

    比如说:1 1 3 3 3 5 5 1

    5 和 1 5和3 然后31 就消完了 可以自己多举个例子 想想 会发现确实是这样的

    2.如果x>n/2:

    n-max 是可以用与消的数嘛 然后 每用一个 数组长度-2 所以得到了这个公式

    n-2*(n-max)

    /*
      * @Author: duck
      * @Date: 2025-11-03 09:59:50
      */
     #include <bits/stdc++.h>
     using namespace std;
     #define int long long
     #define ull unsigned long long
     #define endl '\n'
     #define EPS 1e-8
     #define fi first
     #define se second
     #define lowbit(x) x & (-x)
     const int inf = 0x3f3f3f3f3f3f3f3f; // 正好等于2的60次方
     typedef pair<int, int> pii;
     const int N = 2E5 + 10;
     int vec[N];
     void solve()
     {
         int n;
         cin >> n;
         for (int i = 1; i <= n; i++)
         {
             cin >> vec[i];
         }
     ​
         sort(vec + 1, vec + 1 + n);
         // 不会sort 你们改成冒泡就好了 就是从小到大 排个序
     ​
         int mx = 0;
         int sum = 1;
         for (int i = 1; i + 1 <= n; i++)
         {
             if (vec[i] != vec[i + 1])
             {
                 mx = max(sum, mx);
                 sum = 1;
             }
             else
             {
                 sum++;
             }
         }
         mx = max(sum, mx);
     ​
         if (mx > n / 2)
         {
             cout << n - 2 * (n - mx) << endl;
         }
         else
         {
             if (n % 2)
             {
                 cout << 1 << endl;
             }
             else
             {
                 cout << 0 << endl;
             }
         }
     }
     ​
     signed main()
     {
         ios::sync_with_stdio(false);
         cin.tie(0);
         cout.tie(0);
         int t = 1;
         cin >> t;
         while (t--)
         {
             solve();
         }
         return 0;
     }
    

    第二种:(扩展内容)

    我看有人用桶去写,这道题确实可以用桶的思想去写 但是这道题的数据大小是有1e9的啊 我们之前讲过 数组大小是开不到1e9的 那用桶不就炸了

    所以在这里的话 我们考虑 如何把1e9存起来 这里有两种方法:

    第一种是用STL map去存 map是可以存1e9大小的 然后思想和第一种是一样的

    第二种是我们通过离散化 将1e9 重新赋值 这样下标就小了 因为 我们并不想要这个数值 我们只是想知道这个数字数量是多少 那么我们n最大为2e5 肯定就可以开桶了 是没想到这个规律的暴力方法

    上面说的map和离散化未讲 只是给大家扩展思路 想提前学的可以去了解

    map写法

    ​
     /*
      * @Author: duck
      * @Date: 2025-11-03 09:59:50
      */
     #include <bits/stdc++.h>
     using namespace std;
     #define int long long
     #define ull unsigned long long
     #define endl '\n'
     #define EPS 1e-8
     #define fi first
     #define se second
     #define lowbit(x) x & (-x)
     const int inf = 0x3f3f3f3f3f3f3f3f; // 正好等于2的60次方
     typedef pair<int, int> pii;
     const int N = 2E5 + 10;
     int vec[N];
     void solve()
     {
         int n;
         cin >> n;
         map<int, int> vis;
         int mx = 0;
         for (int i = 1; i <= n; i++)
         {
             cin >> vec[i];
             vis[vec[i]]++;
             mx = max(mx, vis[vec[i]]);
         }
     ​
         if (mx > n / 2)
         {
             cout << n - 2 * (n - mx) << endl;
         }
         else
         {
             if (n % 2)
             {
                 cout << 1 << endl;
             }
             else
             {
                 cout << 0 << endl;
             }
         }
     }
     ​
     signed main()
     {
         ios::sync_with_stdio(false);
         cin.tie(0);
         cout.tie(0);
         int t = 1;
         cin >> t;
         while (t--)
         {
             solve();
         }
         return 0;
     }
    

    离散化写法

    这个写法是很暴力的一个写法 你没想到规律 然后模拟的去写这道题 每次都让最大的和次大的消 模拟这个过程 使用到了优先队列 也是给大家提供一种别的思路 没讲过 感兴趣的自己了解

    #include <bits/stdc++.h>
     using namespace std;
     #define int long long
     #define ull unsigned long long
     #define endl '\n'
     #define EPS 1e-8
     #define fi first
     #define se second
     #define lowbit(x) x & (-x)
     const int inf = 0x3f3f3f3f3f3f3f3f; 
     typedef pair<int, int> pii;
     const int N = 2e5 + 10;
     int newa[N];
     struct QWQ
     {
         int val;
         int id;
     } olda[N];
     ​
     bool cmp(QWQ x, QWQ y)
     {
         return x.val < y.val;
     }
     ​
     void solve()
     {
         int n;
         cin >> n;
         vector<int> vec(n + 1);
         for (int i = 1; i <= n; i++)
         {
             cin >> olda[i].val;
             olda[i].id = i;
         }
     ​
         sort(olda + 1, olda + 1 + n, cmp);
     ​
         int idx = 0;
     ​
         for (int i = 1; i <= n; i++)
         {
             if (i == 1 || olda[i].val != olda[i - 1].val)
             {
                 idx++;
             }
             newa[olda[i].id] = idx;
         }
     ​
         vector<int> b(n + 1);
         for (int i = 1; i <= n; i++)
         {
             b[newa[i]]++;
         }
     ​
         priority_queue<int> que;
         for (int i = 1; i <= idx; i++)
         {
             if (b[i] > 0)
             {
                 que.push(b[i]);
             }
         }
     ​
         while (que.size() >= 2)
         {
             int tp1 = que.top();
             que.pop();
     ​
             int tp2 = que.top();
             que.pop();
     ​
             tp1--;
             tp2--;
     ​
             if (tp1 > 0)
             {
                 que.push(tp1);
             }
     ​
             if (tp2 > 0)
             {
                 que.push(tp2);
             }
         }
     ​
         int ans = 0;
     ​
         while (!que.empty())
         {
             ans += que.top();
             que.pop();
         }
     ​
         cout << ans << endl;
     ​
     }
     signed main()
     {
         ios::sync_with_stdio(false);
         cin.tie(0);
         cout.tie(0);
         int t = 1;
         cin >> t;
         while (t--)
         {
             solve();
         }
         return 0;
     }
    
    • 1

    我叶梓楣也要成为duck大魔王!!!(1)

    信息

    ID
    1174
    时间
    1000ms
    内存
    256MiB
    难度
    6
    标签
    (无)
    递交数
    73
    已通过
    20
    上传者