B. Equalize by Divide - 贪心+思维+构造+数学+排序

发布时间 2023-04-26 13:50:51作者: Yaowww

题意:

  给定一个数组,可以进行任意多次以下操作:

  1.选择第i和第j个数。

  2.使a[i]=a[i]/a[j](向上取整)。

  不可以插入或者删减数组元素,求多少次使数组元素都相同,输出次数以及每次操作的两个下标i,j;如果无法实现输出-1.

分析:

  数组中存在1一定无法实现,或者数组元素都相等直接输出0。

可以将数组排序,使数组中每一个大于最小值的数a[i]都每次与最小的数a[0]进行操作直到a[i]<=a[0],如果数组元素仍然不相同则继续重复以上步骤。

代码:

#include <bits/stdc++.h>

#define endl '\n'

using namespace std;

typedef pair<int,int> pii;
typedef long long ll;

const int N=110;

pii a[N];

void solve()
{
    int t;
    cin>>t;
    while(t--)
    {
        vector<pii> ans;
        int n;
        cin>>n;
        for(int i=0;i<n;i++)
        {
            int x;
            cin>>x;
            a[i]={x,i+1};
        }
        sort(a,a+n);
        if(a[0].first==a[n-1].first)
        {
            cout<<0<<'\n';
            continue;
        }
        if(a[0].first==1)
        {
            cout<<-1<<'\n';
            continue;
        }
        while(1)
        {
            int flag=0;
            for(int i=1;i<n;i++)
            {
                if(a[i].first>a[0].first)
                {
                    flag=1;
                    while(a[i].first>a[0].first)
                    {
                        if(a[i].first%a[0].first==0) a[i].first/=a[0].first;
                        else a[i].first=a[i].first/a[0].first+1;
                        ans.push_back({a[i].second,a[0].second});
                    }
                }
            }
            if(flag==0) break;
            else sort(a,a+n);
        }
        cout<<ans.size()<<'\n';
        for(int i=0;i<ans.size();i++) cout<<ans[i].first<<' '<<ans[i].second<<'\n';
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    
    solve();
}