ANUBTG - Editorial

PROBLEM LINK:

Practice
Contest

Author: Anudeep Nekkanti
Tester: Minako Kojima
Editorialist: Lalit Kundu

DIFFICULTY:

EASY

PRE-REQUISITES:

Sorting, Greedy

PROBLEM:

You have to buy N items of cost A1, A2 … AN. For every two items you buy, they give you two items for free. However, items can be of varying price, they always charge for 2 most costly items and give other 2 as free. For example, if the items cost 1, 1, 2, 2, then you have to pay 4 and take all 4 items.
Find minimum price in which you can buy all items?

QUICK EXPLANATION:

Sort the array A and greedily start choosing from largest elements.

EXPLANATION:

Claim 1:

We should pick the most costliest and second most costliest items in a single bill.

Proof:

Assume x be the most costliest item and y be the second most costliest item. Assume x and y are in different bags. There can be two cases.

  • The bag containing x, has only one element.
    We can add y in the same bill too because we are anyway paying for both, so why two separated bills instead of one.
  • The bag containing x, has more than element. Assume z be the second most costliest item in bag containing x.
    Now we can simply swap y and z. So we will end up x and y being in same bag. Also due to this swapping, there is no change in cost because we were anyway paying for both x and y before.

After picking the most costliest items in a single bill, we should try to pick the third and fourth most costliest items also in the same bag to get most benefit of buy 2, get 2 free scheme. As the third and fourth items will be free.
We can even formally prove this part similar to swapping item used in previous claim.

This concludes the mathematical proof required.

Now that we have chosen one group we’ll choose further groups from remaining array A.

This is the design of our greedy algorithm. We sort the array A first and then start choosing groups of 4 in decreasing order of array A. This will ensure that we make minimum sum.

Pseudo code:

A = input
sort(A)
reverse(A)
ans = 0

for i=0 to N-1:
    //count in answer the index 0,1,4,5,8,9...
    if i%4 < 2:
        ans += A[i]

print ans

Complexity: O(N log N) due to sorting.

SOLUTIONS:

Setter’s solution
Tester’s solution

1 Like

my solution was giving wrong answer. i don’t know why. anyone tell what is the mistake in it.

#include<stdio.h>
int cmpfunc(const void *a,const void *b)
{
    return(*(int*)b-*(int*)a);
}
int main()
{
    int T,N,a[1010]={0},i,sum;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&N);
        for(i=0;i<N;i++)
        scanf("%d",&a[i]);
        qsort(a,N,sizeof(int),cmpfunc);
        //for(i=0;i<N;i++)
       // printf("%d ",a[i]);
        sum=0;
        for(i=0;i<N;i=i+4)
        {
 
            sum+=a[i]+a[i+1];
 
 
        }
        printf("%d\n",sum);
 
    }
    return 0;
}

try this case:

1

1

1

please give me a test case where my program is getting wrong answer:

#include<bits/stdc++.h>
using namespace std;
int main(){
    vector<long long int> inp(10001);
    int t;
scanf("%d",&t);
while(t--){
        int n,i;
    scanf("%d",&n);
    for(i=0;i<n;i++){
        scanf("%lld",&inp[i]);
    }
    sort(inp.rbegin(),inp.rend());
    long long int sum=0;
    int con=0;
    for(i=0;i<n;i++){
        if(con<2){
            sum=sum+inp[i];
            con++;
        }
        else{
            i++;
            con=0;
        }
       
    }
    printf("%lld\n",sum);
}
return 0;
}

try this case…

2

2

2 2

1

1

the problem is that u are not clearing your vector for a new test case!!!

Thanks! :slight_smile:

1 Like

Such a dumb mistake :frowning:

my solution is giving wrong answer. please tell me what are mistake in this code??

#include <bits/stdc++.h>
using namespace std;
#define ll long long int
bool str(ll i,ll j)
{
	return i>j;
}
int main()
{
	ll t,n;
	scanf("%lld",&t);
	while(t--){
		scanf("%lld",&n);
		ll u,x,i,a[n+1],sum=0;
		for(i=0;i<n;i++)scanf("%lld",&a[i]);
		sort(a,a+n,str);
		u=n/4;
		x=n%4;
		for(i=0;i<u;i++){
			sum=sum+a[i*4]+a[i*4+1];
		}
		if(x==1) sum=sum+a[u*4];
		if(x==2) sum=sum+a[u*4]+a[u*4+1];
		if(x==3) sum=sum+a[u*4+1]+a[u*4+2];
		printf("%lld\n",sum);
	}
	return 0;
}

my solution is giving wrong answer. please tell me what is mistake in this code??

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
 
int main() {
long int t,n,a[1009],i;
scanf("%ld",&t);
while(t--){
scanf("%ld",&n);
a[1009]={0};
for(i = 0; i < n;i++){
scanf("%ld",&a[i]);
}
long long int sum = 0;
sort(a,a+n,greater<int>());
i = 0;
while(i < n){
sum = sum + a[i]+a[i+1];
i = i+4;
}
printf("%lld\n",sum);
}
return 0;
}

Can any one explain where my code is wrong.thanks in advance

#include<stdio.h>
#include<stdlib.h>
int cmp(const void *a,const void *b){
return ( (int)a - (int)b );
}
int main(){
int t,n,i;
scanf("%d",&t);
while(t–){
scanf("%d",&n);
int cost[n];
for(i=0;i<n;i++)
scanf("%d",&cost[i]);
long sum=0;
if(n<=4){
qsort(cost,n,sizeof(int),cmp);
sum=cost[n-1]+cost[n-2];}
else{
qsort(cost,n,sizeof(int),cmp);
/for(i=0;i<n;i++)
printf("%d ",cost[i]);
/
for(i=n-1;i>=0;i=i-4){
sum=sum + cost[i]+cost[i-1];
}
}
printf("%ld\n",sum);
}
return 0;
}

Please tell why codechef is telling “wrong answer” to this solution. Answers to the given test cases are coming out right.

ps:i used bubble sort. ill use merge later on.

I had forgotten single input. Sorry, my bad. My doubt is clear

Can someone tell where I’m making a mistake? I checked for the common single input mistake, but I’ve already taken care of it.

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

int main(int argc, const char * argv[]) {

ios_base::sync_with_stdio(false);
cin.tie(NULL);

int t,n,s,i;

cin>>t;

while(t--)
{
    cin>>n;
    
    int A[n+1];
    
    for(i=0;i<n;i++)
        cin>>A[i];
    
    s = 0;
    
    sort(A,A+n,greater<int>());
    
    for(i=0;i<=n-2;)
    {
        s += A[i];
        s += A[i+1];
        
        i = i+4;
    }
    
    if(i==n-1)
        s += A[i];
    
    cout<<s<<"\n";
}

return 0;

}

WA in which case ? have been trying since past so many days. help me out !

Please tell me why am i getting wrong answer for this code.
#include<stdio.h>
int compare(void* i1,void* i2)
{
int *a=(int *)i1;
int *b=(int *)i2;
return *b-*a;
}
int main()
{
int t,n;
int cost[1000];
scanf("%d",&t);
while(t–)
{
scanf("%d",&n);
int i,totalcost=0;
for(i=0;i<n;i++)
scanf("%d",&cost[i]);
if(n<=2)
{
for(i=0;i<n;i++)
totalcost+=cost[i];
}
else
{
qsort(cost,n,sizeof(int),compare);
i=0;
while(i<n)
{
totalcost+=cost[i]+cost[i+1];
i+=4;
}
}
printf("%d\n",totalcost);
}
return 0;
}

https://www.codechef.com/viewsolution/9697384
whats wrong with this solution
all the test cases are working correctly !

#include
#include

using namespace std;

int main()
{
int t,n,i,cost=0;
cin>>t;
while(t–)
{
cin>>n;
int arr[n];
for(i=0;i<n;i++)
cin>>arr[i];
sort(arr,arr+n);
for(i=0;i<n/2;i++)
{int temp;
temp=arr[i];
arr[i]=arr[n-1-i];
arr[n-i-1]=temp;
}
for(i=0;i<n;i++)
{
if(i%4<2)
cost=cost+arr[i];
}
cout<<cost;
}
}

Pls tell the mistake in the above code.It is not giving correct answer.

Help me!

My solution is giving wrong answer.

Solution - Here(in Python)

testcase=int(input())
while(testcase>0):
sum1=0
num=int(input())
lst=[int(i) for i in input().split()]
lst.sort()
count=num-1
while(count>0):
sum1=sum1+lst[count]+lst[count-1]
count=count-4
print(sum1)
testcase-=1

Can someone please tell me why am i getting wrong answer