A-抽奖黑幕

思路

  • 看成删除数组的最大值或最小值使得数组总和最大
  • 添加某个尽可能小的正整数使得删除的数更小

代码部分

#include <bits/stdc++.h>
using namespace std;

const int N = 2e5 + 10;
int a[N];

int main()
{
    int t, n;
    cin >> t;
    while(t --)
    {
        cin >> n;
        for(int i = 1; i < n; i ++) cin >> a[i];
        sort(a + 1, a + n);
        if(a[1] == a[n - 1]) cout << 1 << endl;
        else cout << a[n - 1] << endl;
    }

    return 0;
}

B-生成函数

题目描述

  • 三种无限多的砝码可以左右添加,使得天平平衡

思路

  • 三种砝码在数轴上可以表示无限多的数,但不一定是所有正整数
  • 只需要m % (任意一个数轴上表示数的差值) == 0 就可以平衡
  • 而数的差值一定为a, b, c 三个数的最大公因数的倍数
  • 所以只需要求最大公因数即可

代码部分

#include <bits/stdc++.h>
using namespace std;

int gcd(int a, int b){return b ? gcd(b, a % b) : a;}

int main()
{
    int t, a, b, c, m;
    cin >> t;
    while(t --)
    {
        cin >> a >> b >> c >> m;
        int temp1 = gcd(a, b);
        int temp2 = gcd(temp1, c);
        if(m % temp2) cout << "NO" << endl;
        else cout << "YES" << endl;
    }

    return 0;
}

C-选择交换

  • 代码部分(解释写在注解里)
  • 代码参考——AH-20
#include <bits/stdc++.h>
using namespace std;

const int N = 2e5 + 10;
typedef struct Change{
  //    值     原位置    排序后的位置
    int value, pos_ori, pos_now;
}Change;

Change a[N];
//  m   用于记录输出的位置
int m, output[N][2];

bool cmp1(Change x, Change y){return x.value < y.value;}
bool cmp2(Change x, Change y){return x.pos_ori < y.pos_ori;}
void OutPut(int x, int y);
bool judge_false(int n);
void judge_true(int n);

int main()
{
    int t, n;
    ios::sync_with_stdio(false), cin.tie(nullptr);
    cin >> t;
    while(t --)
    {
        m = 0;
        cin >> n;
      //输入值并记录原位置
        for(int i = 1; i <= n; i ++)
            cin >> a[i].value, a[i].pos_ori = i;
        //如果最大值加上非最小值,那么最小值将无法配对
        sort(a + 1, a + n + 1, cmp1);
        if(judge_false(n))
        {
            //把序列排序为初始时的顺序
            sort(a + 1, a + n + 1, cmp2);
          //可以通过交换时进行处理
            judge_true(n);
        }
    }

    return 0;
}
//判断是否可以通过交换
bool judge_false(int n)
{
    //需要两两相加得到的值
    int judge = a[1].value + a[n].value;
    for(int i = 1; i <= n; i ++)
    {
        if(a[i].value + a[n - i + 1].value != judge)
        {
            cout << "NO\n";
            return false;
        }
        a[i].pos_now = i;
    }
    return true;
}

void judge_true(int n)
{
  //遍历,如果和有序时的顺序不同则记录并交换
  //也就是每个都判断一次位置
    for (int i = 1; i <= n; i++)
        while(a[i].pos_now != i)
        {
            OutPut(i, a[i].pos_now);
            swap(a[i], a[a[i].pos_now]);
        }
    cout << "YES\n";
    cout << m << '\n';
    for(int i = 0; i < m; i ++)
        cout << output[i][0] << ' ' << output[i][1] << '\n';
}
//储存交换的位置
void OutPut(int x, int y)
{
    output[m][0] = x;
    output[m][1] = y;
    m ++;
}