C program Null Parsing - c

I have written a code to calculate the minimum number of coins using Greedy algorithm and Dynamic algorithm, but the Dynamic algorithm part doesn't work properly. There is a Null value going to array, I can't find it. Please HELP me. I need a answer as soon as possible.
#include <stdio.h>
int n;
int denom[]={1,2,4,5,20,25};
int coinCounter(int n);
int main(){
printf("Please Enter a Number : ");
scanf("%d",&n);
int coinmin,orin,i;
orin=n;
i=coinmin=0;
for(i=(sizeof(denom)/4)-1;i>=0;i--){
coinmin =coinmin+n/denom[i];
n=n%denom[i];
}
printf("Coin Min By Greedy Algorithm : %d\n",coinmin);
printf("Dynamic Algorithm : %d\n",coinCounter(orin));
return 0;
}
int coinCounter(int n){
int opt[n];
int largest[n];
int i,j,a;
i=j=0;
for(j=1;j<=n;j++){
opt[j]=10000;
//printf("xxn");
for(i=(sizeof(denom)/4)-1;i>=0;i--){
if(denom[i]==j){
opt[j]=1;
largest[j]=j;
}
else if(denom[i]<j){
a=opt[j-denom[i]]+1;
}
if(a<opt[j]){
opt[j]=a;
largest[j]=denom[i];
}
}
}
return opt[n];
}
I edited the Code as following, but the answer is not coming
int coinCounter(int n){
int opt[n];
int largest[n];
int i,j,a;
i=j=0;
for(j=1;j<n;j++){
opt[j]=10000;
printf("xxn");
for(i=(sizeof(denom)/4)-1;i>=0;i--){
if(denom[i]==j){
opt[j]=1;
largest[j]=j;
}
else if(denom[i]<j){
a=opt[j-denom[i]]+1;
}
if(a<opt[j]){
opt[j]=a;
largest[j]=denom[i];
}
}
}
return opt[n-1];
}
hey these are the results I'm Getting
Please Enter a Number : 8
Coin Min By Greedy Algorithm : 3
Dynamic Algorithm : 1
Another answer I'm getting I can't figure out what I'm doing wrong
Please Enter a Number : 71
Coin Min By Greedy Algorithm : 4
Dynamic Algorithm : 3

1
int opt[n]; // not the right way to do dynamic allocation. Use malloc/calloc
int largest[n];
2
for(j=1;j<=n;j++){
^ array is indexed from 0...n-1, index-n is outside array bounds
Don't do this.

int coinCounter(int n){
int opt[n];
int largest[n]; <---- Don't do this. This does not work like you expect it to.
change to
int coinCounter(int n){
int opt[n];
int *largest = malloc(sizeof(int)*n);
Edit:
Another bug with the algorithm
your variable "a" is not initialized and you are using it in if condition.
think of the case when denom[i]>j
your variable "a" would not be initialized
so depending upon what garbage value it has , results will vary
bug is here , but it shows up when you change opt allocation, because that allocation changes the condition. What I want to say is - if (X<Y), depends on both X and Y. Problem is with X, but because you change Y, the condition changes and you get different result

Related

Algorithm Graph depth - first search

This is graph code, I want to understand Depth-first search algorithm, but I had some problem with this code,
If I input params:
5 5
1 2
1 3
1 5
2 4
3 5
Why cur become return 4 to 2 to 1 in function dfs?
thank your response
#include <stdio.h>
int book[101], sum,e[101][101];
int n,m,a,b;
void dfs(int cur){
int i;
printf("%d ",cur);
sum++;
if(sum==n){
return;
}
//
for(i=1;i<=n;i++){
if( e[cur][i]==1 && book[i]==0 ){
book[i]=1;
dfs(i);
}
}
return;
}
int main(){
int i,j;
scanf("%d %d ", &n,&m);
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(i==j){
e[i][j] = 0;
}else{
e[i][j] = 99999999;
}
};
};
for(i=1;i<=m;i++){
scanf("%d %d" ,&a, &b);
e[a][b] = 1;
e[b][a] = 1;
}
book[1] = 1;
dfs(1);
getchar();
getchar();
return 0;
}
I assume you're asking why your DFS is first exploring 1, then 2, then 4? Well, that's how a DFS works: It greedily goes to the next unvisited vertex. What output would you expect?
Some remarks regarding your code:
To improve the answers that you get, I'd suggest posting code that is a lot cleaner than the code in your question:
Please use variable names that tell your readers what they mean. For example: Use something like bool visited[] instead of int book[].
Use the correct data type! If you want to store whether an edge is there or not, or whether a vertex was visited or not, use bool, not some magic int values.
Global variables are usually not the right thing. There is no reason why all your variables should be global.
Neither is there a reason why the arrays should have the constant size 101.

Rotating array (Larray hackerrank)

I am not able to get the logic behind the solution to the problem . I will be very thankful if someone can explain me the working of it.
Solution:
#include <bits/stdc++.h>
using namespace std;
const int N=1509;
int n;
int a[N];
void input(){
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
}
void sol(){
int K=1;
for (int i=1;i<=n;i++)
for (int j=i+1;j<=n;j++)
K^=(a[i]>a[j]);
if (K) printf("YES\n");
else printf("NO\n");
}
int main() {
int test;
scanf("%d",&test);
while (test--){
input();
sol();
}
return 0;
}
I am not able to get how after xoring each permutation, value of 'k' in the end is determining the answer(ie whether it can be arranged in sorting order) ?
When you rotate a block you change the number of inversions by +/- 2 or 0 (work it out on paper, if you don't trust me). So if the number of inversions in the array is odd you will not be able make it sorted with the given operation. You'll end up with the array almost sorted with all but 2 elements in place (1 inversion) and you can't fix that with the given operation.
What the code does is check if the number of inversions is odd by xoring with itself every time it sees an inversion. You can get the same result if you count the inversions up and check inversions % 2 == 0.

Optimize a segment tree for range maximum queries?

So I need some help again.I recently started doing medium level problems on codechef and hence I am getting TLE quite a lot.
So basically the question is to find the sum of of multiple maximum range queries given in the question.The initial range is given and the next values are calculated by a formula which is given in the problem.
I used segment trees to solve the problem,but I keep getting TLE for some sub-tasks.Please help me optimize this code.
Problem link- https://www.codechef.com/problems/FRMQ
//solved using segment tree
#include <stdio.h>
#define gc getchar_unlocked
inline int read_int() //fast input function
{
char c = gc();
while(c<'0' || c>'9')
c = gc();
int ret = 0;
while(c>='0' && c<='9')
{
ret = 10 * ret + c - '0';
c = gc();
}
return ret;
}
int min(int a,int b)
{
return (a<b?a:b);
}
int max(int a,int b)
{
return (a>b?a:b);
}
void construct(int a[],int tree[],int low,int high,int pos) //constructs
{ //the segment tree by recursion
if(low==high)
{
tree[pos]=a[low];
return;
}
int mid=(low+high)>>1;
construct(a,tree,low,mid,(pos<<1)+1);
construct(a,tree,mid+1,high,(pos<<1)+2);
tree[pos]=max(tree[(pos<<1)+1],tree[(pos<<1)+2]);
}
int query(int tree[],int qlow,int qhigh,int low,int high,int pos)
{ //function finds the maximum value using the 3 cases
if(qlow<=low && qhigh>=high)
return tree[pos]; //total overlap
if(qlow>high || qhigh<low)
return -1; //no overlap
int mid=(low+high)>>1; //else partial overlap
return max(query(tree,qlow,qhigh,low,mid,(pos<<1)+1),query(tree,qlow,qhigh,mid+1,high,(pos<<1)+2));
}
int main()
{
int n,m,i,temp,x,y,ql,qh;
long long int sum;
n=read_int();
int a[n];
for(i=0;i<n;i++)
a[i]=read_int();
i=1;
while(temp<n) //find size of tree
{
temp=1<<i;
i++;
}
int size=(temp<<1)-1;
int tree[size];
construct(a,tree,0,n-1,0);
m=read_int();
x=read_int();
y=read_int();
sum=0;
for(i=0;i<m;i++)
{
ql=min(x,y);
qh=max(x,y);
sum+=query(tree,ql,qh,0,n-1,0);
x=(x+7)%(n-1); //formula to generate the range of query
y=(y+11)%n;
}
printf("%lld",sum);
return 0;
}
Several notes:
It's great you are using fast IO routines.
Make sure you do NOT use modulo operation, because it is VERY slow. To calculate remainder, simply subtract N from the number until it becomes less that N. This would work much faster.
Your algorithm works in O((M+N) * log N) time, which is not optimal. For static RMQ problem, it is better and much simpler to use sparse table. It needs O(N log N) space and O(M + N log N) time.
Well , I think to get 100 points you need to use sparse table.
I tried to optimize your code https://www.codechef.com/viewsolution/7535957 (run time decreased from 0.11 sec to 0.06 sec)
but still not enough to pass subtask 3..

Learning c programming - passing array into function

May i know why is int count, biggest = -12000;? Why must it be -12000 and I do not understand this statement biggest = -12000
If I put biggest = 10000, it can still compile. Appreciate your advise as I am currently learning c programming. Can you please understand as clearly as possible? Thanks in advance!
#include <stdio.h>
#define MAX 10
int array[MAX], count;
int largest(int x[], int y);
int main()
{
/* Input MAX values from the keyboard. */
for (count = 0; count < MAX; count++)
{
printf("\nEnter an integer value:\n ");
scanf_s("&d", &array[count]);
}
/* Call the function and display the return value. */
printf("\n\nLargest value = %d\n", largest(array, MAX));
return 0;
}
/* Function largest() returns the largest value in an integer array */
int largest(int x[], int y)
{
int count, biggest = -12000;
for (count = 0; count < y; count++)
{
if (x[count] > biggest)
biggest = x[count];
}
getchar();
return biggest;
}
If you want to find the largest number in an array you compare all elements against the currently 'biggest' value. Whenever you find a value that's larger you put it in biggest.
To make sure that you find the proper value you must initialize biggest to a sensible value.
Your code initializes biggest to -12000, and therefore it will fail if all elements in the array have values lower than -12000 (unless you know something about the values in the array, but then that should be mentioned in a comment, to explain the unusual initialization value).
Sure it will compile, but that does not mean it will work correctly.
You could initialize biggest to the lowest integer value possible (INT_MIN),
int largest(int x[], int y)
{
int count, biggest = INT_MIN; // lowest integer value possible
for (count = 0; count < y; count++)
{
but a smart trick is to initialize it to the first value in your array.
int largest(int x[], int y)
{
int count, biggest = x[0]; // first value in your array
for (count = 1; count < y; count++) // starting with 2nd element
{
You can work this all out on a piece of paper with e.g. 3 array values, or step through your debugger and see what values the respective variables get.
Instead of assigning the value in starting to biggest, you can compare two elements of the array and after comparing it store maximum value in biggest and after it swap the numbers if greater it would be good approach.
if you use like:
if(x[count]>x[count+1])
biggest=x[count];
x[count]=x[count+1];
x[count+1]=biggest;
code above line in loop.
What you tried assigned a very high value to biggest. It's not a worthy idea.

Trying to write a function to shuffle a deck in C

So all I'm trying to do is take an input from the user of how many cards to use and then randomly assign each card to a different index in an array. I'm having extensive issues getting the rand function to work properly. I've done enough reading to find multiple different ways of shuffling elements in an array to find this one to be the easiest in regards to avoiding duplicates. I'm using GCC and after I input the amount of cards I never get the values from the array back and if I do they're all obscenely large numbers. Any help would be appreciated.
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
void main(){
srand(time(NULL));
int d, c, i, z, l, r;
printf("Enter the deck length: ");
scanf("%d\n ", &c);
int deck[c];
int swap[c];
z = c;
for(l=0; l<c; l++){
swap[l] = l;
}
for(i=z; i=0; i--){
r = rand() / i
deck[i] = swap[r];
for(r; r=(c-1); r++){
swap[r] = swap[(r+1)];
}
}
for(d = 0; d < c; d++){
printf("%d ", deck[d]);
}
return;
}
I can spot one major problem here:
for(i=z; i=0; i--)
^^^
This loop will never execute since you are using assignment(=) and setting i to 0 therefore the condition will always be false, although using equality(==) will still be false in this case, you probably want:
for(i=z; i!=0; i--)
This means you will be using deck unitialized which is undefined behavior. Once you fix that you have a similar problems here:
for(r; r=(c-1); r++){
main has to return int and your return at the end needs to provide a value.
Turning on warning should have allowed you to find most of these issues, for example using -Wall with gcc gives me the following warning for both for loops:
warning: suggest parentheses around assignment used as truth value [-Wparentheses]
Note, see How can I get random integers in a certain range? for guidelines on how to use rand properly.
You basically need to be able to generate 52 numbers pseudo-randomly, without repeating. Here is a way to do that...
First, loop a random number generator 52 times, with a method to ensure none of the random numbers repeat. Two functions in addition to the main() will help to do this:
#include <ansi_c.h>
int NotUsedRecently (int number);
int randomGenerator(int min, int max);
int main(void)
{
int i;
for(i=0;i<52;i++)
{
printf("Card %d :%d\n",i+1, randomGenerator(1, 52));
}
getchar();
return 0;
}
int randomGenerator(int min, int max)
{
int random=0, trying=0;
trying = 1;
while(trying)
{
srand(clock());
random = (rand()/32767.0)*(max+1);
((random >= min)&&(NotUsedRecently(random))) ? (trying = 0) : (trying = 1);
}
return random;
}
int NotUsedRecently (int number)
{
static int recent[1000];//make sure this index is at least > the number of values in array you are trying to fill
int i,j;
int notUsed = 1;
for(i=0;i<(sizeof(recent)/sizeof(recent[0]));i++) (number != recent[i]) ? (notUsed==notUsed) : (notUsed=0, i=(sizeof(recent)/sizeof(recent[0])));
if(notUsed)
{
for(j=(sizeof(recent)/sizeof(recent[0]));j>1;j--)
{
recent[j-1] = recent[j-2];
}
recent[j-1] = number;
}
return notUsed;
}

Resources