小朋友分糖果

B3. 小朋友分糖果

Time limit per test: 1.0 seconds

Memory limit: 256 megabytes

有 n 个小朋友,标号为 1 到 n,每个小朋友有一些糖果,第 i 个小朋友拥有糖果数量为 ai

为了使得每个小朋友拥有相同的糖果,现提供如下操作:选择两个小朋友组成一个有序对 (u,v) (1u,vn,uv),然后记两个小朋友拥有的糖果总和为 S,然后令 au=S2av=S2

即:

function do_something(u, v):
    S := (a[u] + a[v])
    a[u] := floor(S / 2)
    a[v] := ceil(S / 2)

请构造一系列操作,使得所有小朋友最终拥有相同的糖果。

Input

第一行一个整数 n (1n1 000)。

第二行 n 个整数用空格隔开:a1,a2,,an (0ai109)。

Output

题目保证有解。输出:

  • 第一行:输出一个整数 m (0m10 000),表示操作序列的长度。
  • 接下来依次输出操作,每一行输出两个整数 u,vu,v 的含义见题意。

所以你的程序应该在 10 000 步以内完成任务。给定数据保证存在一种方案能够完成目标。你可以输出任意一种方案。

Examples

input
4
1 3 1 3
output
2
1 4
2 3

尽量每天做一道题以保持手感。

中文题意不解释。做法是每次取最大的和最小的进行处理。

那就很简单了。

这道题主要练了multiset的用法。erase可以用于删除某一些元素可以通过传迭代器和传值两种方法。

还有记住end()不是指向最后一个元素而是最后一个元素后一个位置。

STL大法好。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <set>
#include <map>
#include <set>
#include <vector>
#define vi vector<int>
#define ll long long
#define P pair<int,int>
using namespace std;
int main()
{
    // freopen("out.txt","w",stdout);
    ios::sync_with_stdio(false);
    cin.tie(0);
    multiset<node> q;
    ll sum = 0;
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        int temp; cin >> temp;
        sum += temp;
        q.insert(node(temp, i));
    }
    int base = sum / n;
    vector<P> ans;
    while(!(q.begin()->a == base && q.rbegin()->a == base))
    {
        ans.push_back(P(q.begin()->idex, q.rbegin()->idex));
        int au = q.begin()->a, av = q.rbegin()->a;
        int aui = q.begin()->idex, avi = q.rbegin()->idex;
        double temp = au + av;
        q.erase(q.begin());
        multiset<node> :: iterator ii = q.end();
        ii--;
        q.erase(ii);
        q.insert(node(floor(temp / 2),aui));
        q.insert(node(ceil(temp / 2),avi));
    }
    cout << ans.size() << endl;
    for(auto i : ans)
        cout << i.first << ' ' << i.second <<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sinat_37158899/article/details/80529522
今日推荐