【发布时间】:2020-10-27 20:07:50
【问题描述】:
有 2 个 i/p 数组。当它们具有完全相同的数字时,它们是相同的。为了使它们相同,我们可以交换它们的元素。交换是有代价的。如果我们交换 a 和 b 元素,那么 cost = min(a, b)。
在制作阵列相同的同时,成本应该是最低的。
如果无法使数组相同,则打印 -1。
i/p:
3 6 6 2
2 7 7 3
o/p :
4
在这里我交换了 (2,7) 和 (2,6)。所以最小成本 = 2 + 2 = 4。
逻辑:
-
制作 2 张地图,用于存储 i/p 数组元素的频率。
-
如果aMap中的元素“a”也存在于bMap中,那么我们必须考虑a = abs(aMap中的freq(a) - bMap中的freq(a))的交换次数
-
如果元素的频率是“奇数”,则不可能使它们相同。
-
否则,从两个地图中添加总交换并使用
查找成本 成本 = 最小元素 * 总交换次数
这里是代码
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
int main()
{
int t;
cin >> t;
while(t--)
{
int size;
long long int cost = 0;
cin >> size;
bool flag = false;
map<long long int, int> aMap;
map<long long int, int> bMap;
// storing frequency of elements of 1st input array in map
for( int i = 0 ; i < size; i++)
{
long long int no;
cin >> no;
aMap[no]++;
}
// storing frequency of elements of 2nd input array in map
for(int i = 0 ; i < size; i++)
{
long long int no;
cin >> no;
bMap[no]++;
}
// fetching smallest element (i.e. 1st element) from both map
long long int firstNo = aMap.begin()->first;
long long int secondNo = bMap.begin()->first;
long long int smallestNo;
// finding smallest element from both maps
if(firstNo < secondNo)
smallestNo = firstNo;
else
smallestNo = secondNo;
map<long long int, int> :: iterator itr;
// trying to find out total number of swaps we have to perform
int totalSwapsFromA = 0;
int totalSwapsFromB = 0;
// trversing a map
for(itr = aMap.begin(); itr != aMap.end(); itr++)
{
// if element "a" in aMap is also present in bMap, then we have to consider
// number of swapping = abs(freq(a) in aMap - freq(a) in bMap)
auto newItr = bMap.find(itr->first);
if(newItr != bMap.end())
{
if(itr->second >= newItr->second)
{
itr->second -= newItr->second;
newItr->second = 0;
}
else
{
newItr->second -= itr->second;
itr->second = 0;
}
}
// if freq is "odd" then, this input is invalid as it can not be swapped
if(itr->second & 1 )
{
flag = true;
break;
}
else
{
// if freq is even, then we need to swap only for freq(a)/ 2 times
itr->second /= 2;
// if swapping element is smallest element then we required 1 less swap
if(itr->first == smallestNo && itr->second != 0)
totalSwapsFromA += itr->second -1;
else
totalSwapsFromA += itr->second;
}
}
// traversing bMap to check whether there any number is present which is
// not in aMap.
if(!flag)
{
for(itr = bMap.begin(); itr != bMap.end(); itr++)
{
auto newItr = aMap.find(itr->first);
if( newItr == aMap.end())
{
// if frew is odd , then i/p is invalid
if(itr->second & 1)
{
flag = true;
break;
}
else
{
itr->second /= 2;
// if swapping element is smallest element then we required 1 less swap
if(itr->first == smallestNo && itr->second != 0)
totalSwapsFromB += itr->second -1;
else
totalSwapsFromB += itr->second;
}
}
}
}
if( !flag )
{
cost = smallestNo * (totalSwapsFromB + totalSwapsFromA);
cout<<"cost "<<cost <<endl;
}
else
cout<<"-1"<<endl;
}
return 0;
}
上面的代码没有错误,但是给出了错误的答案并且没有被接受。
任何人都可以改进此代码/逻辑吗?
【问题讨论】:
-
不要使用可变长度数组,
a[size]andn[size]和aHash[N]和bHash[N],即使你的编译器接受它们(如 g++),使用的大小至少因为 N 值是可能超出堆栈的大小 -
奇怪的是,就在昨天我们还有Making Two Arrays Identical by swapping elements [closed] :)
-
正确的解决方案是交换
(6, 7),所以成本是1。我不知道你的代码为什么这么复杂。我认为它在 20 行内是可行的。 -
在
aHash[a[i]]中,你怎么能认为a[i]是cin >> a[i];之后的aHash 中的有效索引?bHash[b[i]]中的相同 -
@MarekR 如果我们交换(6,7),那么成本将为 6。(成本 = min(交换元素 a,b))