A. Make it Beautiful 构造贪心
题意:
给定n个元素,要构造一个序列A,使得任意不等于之前所有元素的累和
思路:
容易想到先排序,再从大到小摆放,但是如果给定的n个元素都相等就会出错。更稳妥的是一大一小链式摆放,特判一下所有元素是否相等
#include <bits/stdc++.h>
#define int ll
signed main()
{
IO;
int t; cin >> t;
while (t--)
{
int n; cin >> n;
vector<int> a(n + 1), b;
for (int i = 1; i <= n; i++)
cin >> a[i];
sort(a.begin() + 1, a.end());
for (int i = 1; i <= n / 2; i++)
{
b.push_back(a[i]);
b.push_back(a[n - i + 1]);
}
if (n & 1)
b.push_back(a[n / 2 + 1]);
int sum = 0;
bool f = 1;
for (int i = 0; i < n; i++)
{
if (sum == b[i])
{
f = 0;
break;
}
sum += b[i];
}
if (f)
{
cout << "YES\n";
for (auto x : b)
cout << x << ' ';
cout << endl;
}
else
cout << "NO\n";
}
return 0;
}
B. Matrix of Differences
题意:
构造一个大小为n*n的矩阵,共有n*n个元素,从1到n*n各出现一次,对矩阵进行相邻元素求绝对值的操作,得到全部相邻元素的绝对值,记共有m种不同的绝对值,要求构造一个m最大的矩阵,并输出。答案不唯一,
思路:
盲猜任意n*n的矩阵,最大有n*n-1种不同绝对值。通过s型摆放可以构造出符合要求的矩阵
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl "\n"
const int N = 55;
int a[N][N];
bool cmp(int x, int y)
{
return x > y;
}
void solve()
{
int n;
cin >> n;
int mx = n * n, mn = 1;
for (int i = 1; i <= n; i++)
{
if (i & 1)
{
for (int j = 1; j <= n; j++)
{
if (j & 1)
a[j][i] = mn++;
else
a[j][i] = mx--;
}
}
else
{
if (n & 1)
{
for (int j = n, cnt = 1; j >= 1; j--, cnt++)
{
if (cnt & 1)
a[j][i] = mx--;
else
a[j][i] = mn++;
}
}
else
{
for (int j = n, cnt = 1; j >= 1; j--, cnt++)
{
if (cnt & 1)
a[j][i] = mn++;
else
a[j][i] = mx--;
}
}
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cout << a[i][j] << " ";
}
cout << endl;
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
a[i][j] = 0;
}
}
}
int main()
{
int T;
cin >> T;
while (T--)
{
solve();
}
return 0;
}
C. Yet Another Tournament
题意:
有n+1个人参加比赛,两两相互比赛,出自己以外其余n个人,序号分别为1到n,对于i和j两个参赛者,如果i > j,则i和j的比赛,i会赢。但是自己比较特殊,最开始自己有m分钟的时间进行准备,要想击败i就需要花费 的时间去准备,最终两两比赛完成,按照每个人的胜利场次进行排名,相同胜利场次名次一样,要求计算自己最佳的比赛名次。
思路:
首先除自己以外,其余人的基础胜利场次为0到n-1。自己肯定要尽量击败更多的人,于是按照的大小进行升序排序,对于最初的m分钟的准备时间找到最大的击败数量,若最大击败x人,如果序号为x+1的对手在击败的人之中那么名次为n-x,不在,名次就为n-x+1
#include <bits/stdc++.h>
#define int ll
signed main()
{
IO;
int t; cin >> t;
while (t--)
{
int n, m;
cin >> n >> m;
vector<int> a(n + 1), b(n+1);
for (int i = 1; i <= n; i++)
cin >> a[i];
b = a;
sort(b.begin() + 1, b.end());
int ans = n + 1, sum = 0;
for (int i = 1; i <= n; i++)
{
sum += b[i];
if (sum <= m)
ans = min(ans, max(1ll,n - i+1));
if (i<n&&sum + max(a[i + 1] - b[i], 0ll) <= m)
ans = min(ans, max(1ll, n - i));
}
cout << ans << endl;
}
return 0;
}