比赛链接Dashboard - Educational Codeforces Round 155 (Rated for Div. 2) - Codeforces
题目链接Problem - 1879B - Codeforces
和codeforces老套路一样,这题还是思维题,其实我刚开始读题也读了半天。
先讲一下我一开始的错误想法,我一开始认为的是棋盘上任意一个位置,这个位置的行或者列,必须至少一个筹码,并且这个筹码的行列的值必须要等于这个任意位置的横纵坐标之一,或者都等于。后来读着读着发现不对劲了,因为如果是我一开始理解的这样,那么这个测试样例都是错的,但是cf的测试样例几乎不可能出错误。所以我得重新读题。
现在讲一下正确的思路:首先我们发现这个两个数组a,b的值,我们不需要重新排列,他相当于重新给坐标轴赋值,并且这个坐标轴不是单调的,比如x轴可能是2,5,9,7这种,y轴同理。所以我们再回到题目,题目说想要最小值,那么我们不妨,找a数组的min值,然后用b数组的每一个与它相加,求出总和。然后我们再操作一次找出b数组的min值,让a数组的每个值与b数组的min值相加,求出总和,两个总和进行对比,输出最小的那个。如果不理解我说的意思,建议动手画一画棋盘,你多尝试几次,你就知道我在说什么了,还是那句话,b题几乎是在找规律。
接下来是代码实现
#include <bits/stdc++.h>
#define int long long
#define ll long long
#define endl '\n'
using namespace std;
void solve()
{
int n;
cin>>n;
vector<int> a(n+1);
vector<int> b(n+1);
a.clear();
b.clear();
int max_1 = -1;//找出a数组的max
int max_2 = -1;//找出b数组的max
int min_1 = 1e10;//找出a数组的min
int min_2 = 1e10;//找出b数组的min
int cnt = 0;//求和1,ps我忘记这个求和哪个了,不过问题不大,乱序也没啥事
int sum = 0;//求和2
for(int i = 1;i<n+1;i++)
{
cin>>a[i];
if(a[i]<=min_1) min_1 = a[i];
if(a[i]>=max_1) max_1 = a[i];
}
for(int i = 1;i<n+1;i++)
{
cin>>b[i];
if(b[i]>=max_2) max_2 = b[i];
if(b[i]<=min_2) min_2 = b[i];
}
for(int i = 1;i<=n;i++)
{
cnt+=(b[i]+min_1);
}
for(int i = 1;i<=n;i++)
{
sum+=(a[i]+min_2);
}
if(sum>=cnt)//比较
{
cout<<cnt<<'\n';
}
else
{
cout<<sum<<'\n';
}
}
signed main(void)
{
std::ios::sync_with_stdio(false);//关闭输入输出流
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--)
{
solve();
}
return 0;
}