WA on SCUBADIV spoj - algorithm

I am trying to solve http://www.spoj.pl/problems/SCUBADIV/ this question on spoj.com But I am getting WA. I have written a recursive solution and used memorization.
Can anyone help me to find my mistake? Thanks in advance :)
int oxygen[1010],nitrogen[1010],weight[1010],n;
int dp[200][200];
// oxy is the amnt of oxygen needed , nitro is the amnt of nitrogen needed , pos denotes element picked up till now
int calculate (int oxy , int nitro ,int pos){
long long int min = 10000000;
if(oxy <=0 && nitro <=0)
return 0;
if(dp[oxy+79][nitro+21]!=-1)
return dp[oxy+79][nitro+21];
else{
for(int i=pos+1;i<n;i++){
int val = calculate (oxy - oxygen[i] ,nitro - nitrogen[i] , i)+ weight[i];
if(val<min){
min = val;
}
}
}
dp[oxy+79][nitro+21]=min;
return min;
}
int main(){
int test;
int i,oxy,nitro;
cin>>test;
while(test--){
cin>>oxy>>nitro;
cin>>n;
for( i=0;i<n;i++){
cin>>oxygen[i]>>nitrogen[i]>>weight[i];
}
for(i=0;i<110;i++){
for(int j=0;j<110;j++){
dp[i][j]=-1;
}
}
long long int min =1000000;
for(i=0;i<n;i++){
int val = calculate(oxy-oxygen[i],nitro-nitrogen[i], i)+weight[i];
if(val<min)
min = val;
}
cout<<min<<endl;
}
return 0;
}
As pointed out i looked and found that i read the wrong constraints for oxygen and nitrogen.. i modoified my code for that constraint still it gives wrong answer
int oxygen[1010],nitrogen[1010],weight[1010],n;
int dp[900][900];
// oxy is the amnt of oxygen needed , nitro is the amnt of nitrogen needed , pos denotes element picked up till now
int calculate (int oxy , int nitro ,int pos){
long long int min = 800000;
if(oxy <=0 && nitro <=0)
return 0;
if(dp[oxy+800][nitro+100]!=-1)
return dp[oxy+800][nitro+100];
else{
for(int i=pos+1;i<n;i++){
int val = calculate (oxy - oxygen[i],nitro - nitrogen[i] , i)+ weight[i];
if(val<min){
min = val;
}
}
}
dp[oxy+800][nitro+100]=min;
return min;
}
int main(){
int test;
int i,oxy,nitro;
cin>>test;
while(test--){
cin>>oxy>>nitro;
cin>>n;
for( i=0;i<n;i++){
cin>>oxygen[i]>>nitrogen[i]>>weight[i];
}
for(i=0;i<100+800;i++){
for(int j=0;j<800+100;j++){
dp[i][j]=-1;
}
}
//cout<<"here";
long long int min =800000;
for(i=0;i<n;i++){
int val = calculate(oxy-oxygen[i],nitro-nitrogen[i], i)+weight[i];
if(val<min)
min = val;
}
cout<<min<<endl;
}
return 0;
}

I believe your code outputs 119(actually from time to time I get runtime error) on this test case:
1
22 175
5
3 36 120
10 25 129
5 50 250
1 45 130
4 20 119
While this apparently is not the correct answer. Hope this helps.

Related

spoj ACPC10D -Why i am getting the wrong answer?

Here's my code .It is passing the testcase given in the problem statement.
Link for problem :http://www.spoj.com/problems/ACPC10D/
tri[i][j] stores the min value to reach at index (i,j) from tri[0][1].
//trigraphs-dp
#include<iostream>
#include<limits.h>
using namespace std;
int tri[1000000][3];
int min(int a,int b)
{
if(a<=b)
return a;
else
return b;
}
int main()
{
int n,t=1;
while(cin>>n)
{
if(n==0)
break;
for(int i=0;i<n;i++)
for(int j=0;j<3;j++)
cin>>tri[i][j];
tri[0][0]=INT_MAX;
tri[0][2]=tri[0][1]+tri[0][2];
//cout<<tri[0][2];
int a,b,c,d;
for(int i=1;i<n;i++)
for(int j=0;j<3;j++)
{
a=tri[i-1][j];
b=(j==2)?INT_MAX:tri[i-1][j+1];
c=(j==0)?INT_MAX:tri[i-1][j-1];
d=(j==0)?INT_MAX:tri[i][j-1];
tri[i][j]+=min(min(a,b),min(c,d));
}
cout<<t<<". "<<tri[n-1][1]<<"\n";
}
return 0;
}
1- You forgot to increment t in the end of the loop
2- Define tri as long long type because of possible overflow when you add up numbers.

finding shortest path of all nodes from a given node using BFS

when i increase or decrease INF value the Output Behaves Unexpectedly..
I think INF should not have any effect on the output..
length of each edge is 6
for input
1
4 2
1 2
1 3
1
the output is 6 6 -1
when I change INF to 1e8 the output is 0 0 0
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
#define MAX 2000
#define INF 1000000
vector<int> adj[MAX];
int d[MAX];
bool visited[MAX];
void initialise(){
for(int i=0;i<=MAX;i++){
visited[i]=false;
}
}
void shortestPathBfs(int start){
queue<int> q;
q.push(start);
visited[start]=true;
d[start]=0;
while(!q.empty()){
int p=q.front();
q.pop();
for(int i=0;i<adj[p].size();i++){
int v=adj[p][i];
if(!visited[v] && d[v]>d[p]+6){
d[v]=d[p]+6;
q.push(v);
visited[v]=true;
}
}
}
}
int main(){
int T,N,M,S,x,y;
cin>>T;
while(T--){
cin>>N>>M;
for(int i=0;i<M;i++){
cin>>x>>y;
adj[x].push_back(y);
adj[y].push_back(x);
}
cin>>S;
initialise();
memset(d,INF,sizeof(d));
shortestPathBfs(S);
for(int i = 1; i <=N; i++) {
if(i == S)
continue;
if(d[i] >= INF)
cout<<"-1"<<" ";
else
cout<<d[i]<<" ";
}
}
}
The problem is with
memset(d,INF,sizeof(d));
memset() only fills memory with a byte value. Here it will wind up filling the array with the least significant byte of the int value INF. To fix it, create an explicit for loop or use std::fill() instead.

quick select is not working for all indexes

I am trying to implement quick select referring to a algorithm given in the following link
http://www.cs.yale.edu/homes/aspnes/pinewiki/QuickSelect.html
But the program crashes for many k values, and works fine for only few. Kindly guide me where i am doing wrong.
#include <stdio.h>
#include <stdlib.h>
int a1[10];
int a2[10];
int quickselect(int a[], int k,int len){
int r = rand()%(len-1);
int pivot = a[r];
int i =0;
int len1=0,len2=0;
for(i=0 ;i<len;i++){
if(a[i]<pivot)
a1[len1++]=a[i];
else if(a[i]>pivot)
a2[len2++] = a[i];
else
continue;
}
if(k<=len1)
return quickselect(a1, k,len1);
else if (k > len-len2)
return quickselect(a2, k - (len-len2),len2);
return pivot;
}
int main()
{
int a[7] = {8,3,2,6,1,9,5};
int val = quickselect(a,3,7);
printf("%d \n",val);
return 0;
}
I have test your code. I think you should change int r = rand()%(len-1) to int r = rand()%len because when len==1you will get a floating point exception.

Finding an efficient algorithm

You are developing a smartphone app. You have a list of potential
customers for your app. Each customer has a budget and will buy the app at
your declared price if and only if the price is less than or equal to the
customer's budget.
You want to fix a price so that the revenue you earn from the app is
maximized. Find this maximum possible revenue.
For instance, suppose you have 4 potential customers and their budgets are
30, 20, 53 and 14. In this case, the maximum revenue you can get is 60.
**Input format**
Line 1 : N, the total number of potential customers.
Lines 2 to N+1: Each line has the budget of a potential customer.
**Output format**
The output consists of a single integer, the maximum possible revenue you
can earn from selling your app.
Also, upper bound on N is 5*(10^5) and upper bound on each customer's budget is 10^8.
This is a problem I'm trying to solve . My strategy was to sort the list of budgets and then multiply each of those with its position-index in the sequence - and then print the max of the resulting sequence. However this seems to be quite time-inefficient (at least in the way I'm implementing it - I've attached the code for reference). My upper bound on time is 2 seconds. Can anyone help me find a
more time-efficient algorithm (or possibly a more efficient way to implement my algorithm) ?
Here is my solution :
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
using namespace std;
long long max(long long[],long long);
void quickSortIterative(long long[],long long,long long);
long long partition(long long[],long long,long long);
void swap(long long*,long long*);
int main(){
long long n,k=1;
scanf("%lld",&n);
if(n<1 || n > 5*((long long)pow(10,5))){
exit(0);
}
long long budget[n],aux[n];
for(long long i=0;i<n;i++){
scanf("%lld",&budget[i]);
if(budget[i]<1 || budget[i] > (long long)pow(10,8)){
exit(0);
}
}
quickSortIterative(budget,0,n-1);
for(long long j=n-1;j>=0;j--){
aux[j] = budget[j]*k;
k++;
}
cout<<max(aux,n);
return 0;
}
long long partition (long long arr[], long long l, long long h){
long long x = arr[h];
long long i = (l - 1);
for (long long j = l; j <= h- 1; j++)
{
if (arr[j] <= x)
{
i++;
swap (&arr[i], &arr[j]);
}
}
swap (&arr[i + 1], &arr[h]);
return (i + 1);
}
void swap ( long long* a, long long* b ){
long long t = *a;
*a = *b;
*b = t;
}
void quickSortIterative(long long arr[], long long l, long long h){
long long stack[ h - l + 1 ];
long long top = -1;
stack[ ++top ] = l;
stack[ ++top ] = h;
while ( top >= 0 ){
h = stack[ top-- ];
l = stack[ top-- ];
long long p = partition( arr, l, h );
if ( p-1 > l ){
stack[ ++top ] = l;
stack[ ++top ] = p - 1;
}
if ( p+1 < h ){
stack[ ++top ] = p + 1;
stack[ ++top ] = h;
}
}
}
long long max(long long arr[],long long length){
long long max = arr[0];
for(long long i=1;i<length;i++){
if(arr[i]>max){
max=arr[i];
}
}
return max;
}
Quicksort can take O(n^2) time for certain sequences (often already sorted sequences are bad).
I would recommend you try using a sorting approach with guaranteed O(nlogn) performance (e.g. heapsort or mergesort). Alternatively, you may well find that using the sort routines in the standard library will give better performance than your version.
You might use qsort in C or std::sort in C++, which is most likely faster than your own code.
Also, your "stack" array will cause you trouble if the difference h - l is large.
I have used STL library function sort() of C++. It's time complexity is O(nlogn). Here, you just need to sort the given array and check from maximum value to minimum value for given solution. It is O(n) after sorting.
My code which cleared all the test cases :
#include <algorithm>
#include <stdio.h>
#include <cmath>
#include <iostream>
using namespace std;
int main(){
long long n, a[1000000], max;
int i, j;
cin>>n;
for(i = 0; i < n; i++){
cin>>a[i];
}
sort(a, a + n);
max = a[n - 1];
for(i = n - 2; i >= 0; i--){
//printf("%lld ", a[i]);
if(max < (a[i] * (n - i)))
max = a[i] * (n - i);
}
cout<<max<<endl;
return 0;
}
I dont know if my answer is right or wrong please point out mistakes if there is any
#include<stdio.h>
void main()
{
register int i,j;
long long int n,revenue;
scanf("%Ld",&n);
long long int a[n];
for(i=0;i<n;i++)
scanf("%Ld",&a[i]);
for (i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if(a[i]>a[j])
{
a[i]=a[i]+a[j];
a[j]=a[i]-a[j];
a[i]=a[i]-a[j];
}
}
}
for(i=0;i<n;i++)
a[i]=(n-i)*a[i];
revenue=0;
for(i=0;i<n;i++)
{
if(revenue<a[i])
revenue=a[i];
}
printf("%Ld\n",revenue);
}
passed all the test cases
n=int(input())
r=[]
for _ in range(n):
m=int(input())
r.append(m)
m=[]
r.sort()
l=len(r)
for i in range(l):
m.append((l-i)*r[i])
print(max(m))
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main() {
// your code goes here
long long n;
std::cin >> n;
long long a[n];
for(long long i=0;i<n;i++)
{
std::cin >> a[i];
}
sort(a,a+n);
long long max=LONG_MIN,count;
for(long long i=0;i<n;i++)
{
if(a[i]*(n-i)>max)
{
max=a[i]*(n-i);
}
}
std::cout << max << std::endl;
return 0;
}
The following solution is in C programming Language.
The Approach is:
Input the number of customers.
Input the budgets of customers.
Sort the budget.
Assign revenue=0
Iterate through the budget and Multiply the particular budget with the remaining budget values.
If the previous-revenue < new-revenue. assign the new-revenue to revenue variable.
The code is as follows:
#include <stdio.h>
int main(void) {
int i,j,noOfCustomer;
scanf("%d",&noOfCustomer);
long long int budgetOfCustomer[noOfCustomer],maximumRevenue=0;
for(i=0;i<noOfCustomer;i++)
{
scanf("%Ld",&budgetOfCustomer[i]);
}
for(i=0;i<noOfCustomer;i++)
{
for(j=i+1;j<noOfCustomer;j++)
{
if(budgetOfCustomer[i]>budgetOfCustomer[j])
{
budgetOfCustomer[i]=budgetOfCustomer[i] + budgetOfCustomer[j];
budgetOfCustomer[j]=budgetOfCustomer[i] - budgetOfCustomer[j];
budgetOfCustomer[i]=budgetOfCustomer[i] - budgetOfCustomer[j];
}
}
}
for(i=0;i<noOfCustomer;i++)
{
budgetOfCustomer[i]=budgetOfCustomer[i]*(noOfCustomer-i);
}
for(i=0;i<noOfCustomer;i++)
{
if(maximumRevenue<budgetOfCustomer[i])
maximumRevenue=budgetOfCustomer[i];
}
printf("%Ld\n",maximumRevenue);
return 0;
}

How to print numbers in a spiral order?

Thank you ,
i am trying to solve a project euler problem it wants me to print the sum of
21 22 23 24 25
20 7 8 9 10
19 6 1 2 11
18 5 4 3 12
17 16 15 14 13
this is formed by starting with the number 1 and moving to the right in a clockwise direction for a 5 by 5 matrix but i am in trouble writing a code for the spiral matrix !!
It is Highly recommended to do project Euler problems on your own and ask for help if you are really stuck
here is how i will write a code in c to print a spiral as suggested in the question
#include<stdio.h>
main()
{
int i,j,nq=9;//nq is a odd number which represents the order of the matrix
int lim=(int)nq/2,cnt=2;
int a[nq][nq];
for(i=0;i<nq;i++){
for(j=0;j<nq;j++)
a[i][j]=0;
}
a[lim][lim]=1;
a[lim][lim+1]=2;
int i1=lim,j1=lim+1;i=lim,j=lim;
while(1){
if(cnt>(nq*nq))
break;
cnt++;
if(i==i1)
{ j=j1;
if(i<=lim)
{
i=i1;
if(a[i1+1][j1]==0)
a[++i1][j]=cnt;
else
a[i1][++j1]=cnt;
}
else
{ i=i1;
if(a[i1-1][j1]==0)
a[--i1][j1]=cnt;
else
a[i1][--j1]=cnt;
}
}
else
{ i=i1;
if(j<lim)
{
j=j1;
if(a[i1][j+1]==0)
a[i1][++j1]=cnt;
else
a[--i1][j1]=cnt;
}
else
{ j=j1;
if(a[i1][j1-1]==0)
a[i1][--j1]=cnt;
else
a[++i1][j1]=cnt;
}
}
}
for(i=0;i<nq;i++){
for(j=0;j<nq;j++)
printf(" %d ",a[i][j]);
printf("\n");
}
}
I Googled your question http://projecteuler.net/problem=28 this can also be solved by taking advantage of its mathematical nature note that
Top right corner is n^2
and other corners can be shown to be n^2-2n+2 ,n^2-n+1, and n^2-3n+3. you just need to sum those corners which comes to be
= 4*n^2 - 6*n + 6
hence the final answer can be calculated by iterating over every second number from 1001 to 3
long int sum(int n){
long int sum=1;
while(n>1){
sum=sum+4*n*n-6*n+6;
n=n-2;
}
return sum;
}
I dont know whether you actually want to print the spiral but see below for my solution for #28 written in Python 2.7.
l = [1]
def corners(step,l):
counter = 0
while counter < 4:
l.append(max(l)+step)
counter +=1
return l
step = 2
while step < 1001:
l = corners(step, l)
step += 2
print sum(l)
void printSpiral(int A[3][5],int m, int n)
{
int T=0; int B=m-1; int L=0; int R=n-1;
int dir=0;
int i =0; int j=0; int k=0; int l=0;
while(T<=B && L<=R)
{
//printf("dir %d ",dir);
if(dir == 0)
{
for( i=L;i<=R;i++)
{
printf("%d ",A[T][i]);
//printf("\n");
}
T++;
dir=1;
}
else if(dir == 1)
{
// printf("%d R ",R);
for( j=T;j<= B;j++)
{
printf("%d ",A[j][R]);
//printf("\n");
//printf("dir1");
}
dir=2;
R--;
}
else if(dir == 2)
{
for(k=R;k>= L;k--)
{
printf("%d ",A[B][k]);
}
dir=3;
B--;
}
else if(dir == 3)
{
for( l=B;l>= T;l--)
{
printf("%d ",A[l][L]);
}
L++;
dir=0;
}
}
}

Resources