Find segmentation fault while passing map to function C++ - c++

I can't find the segmentation fault which is occuring on the line where I am calling calculate_grundy in main. Please help.
I have also added a screenshot of my debugger while debugging the code.
This is a question of a running contest so please don't answer logic problems instead of helping me in finding the segmentation fault.
I am passing the dp map for storing the subproblems, as done in dynamic programming.
#include<bits/stdc++.h>
#define ll long long int
using namespace std;
ll calculate_mex(unordered_set<ll> Set)
{
ll mex = 0;
while(Set.find(mex)!=Set.end())
{
mex++;
}
return mex;
}
ll calculate_grundy(ll n,ll m,map<pair<ll,ll>,ll> &dp)
{
auto it = dp.find(make_pair(n,m));
if(it!=dp.end())
{
return it->second;
}
else
{
ll ans;
ll greater = max(n,m);
ll smaller = min(n,m);
if(n==m || m==0 || n==0)
{
return 0;
}
else if(n==1 || m==1)
{
return n==1?m:n;
}
unordered_set<ll> Set;
ll limit = greater%smaller;
for(ll i=1;i<=limit;i++)
{
ll mult = smaller*i;
Set.insert(calculate_grundy(greater-mult,smaller,dp));
}
ans = calculate_mex(Set);
dp.insert(make_pair(make_pair(n,m),ans));
return ans;
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
ll t;
cin>>t;
while(t--)
{
ll n,m;
cin>>n>>m;
map<pair<ll,ll>,ll> dp;
if(calculate_grundy(n,m,dp)==0)
{
cout<<"Ari"<<"\n";
}
else
{
cout<<"Rich"<<"\n";
}
}
}

Related

Why am I getting SIGCONT error on codechef ide?

I am getting SIGCONT error while running the code in codechef ide whereas on my local ide the same code runs fine.
The problem code is "TYPING" and it is from Snackdown Practice Contest: Beginner.
The code is below:
#include <iostream>
#include <iterator>
#include <map>
#include <string>
typedef long long ll;
ll FindCount(const char* str,ll num){
char previous =str[0];
ll individual_count=2;
for(ll i =1 ;i<num;i++){
if(previous=='d'||previous=='f'){
if(str[i]=='d'||str[i]=='f'){
individual_count+=4;
}
else{
individual_count+=2;
}
}
else{
if(str[i]=='j'||str[i]=='k'){
individual_count+=4;
}
else{
individual_count+=2;
}
}
previous=str[i];
}
return individual_count;
}
int main()
{
ll t;
std::cin>>t;
while(t--)
{
std::map<std::string,ll> m;
ll count=0;
ll n=0;
std::cin>>n;
while(n--){
std::string str;
std::cin>>str;
std::map<std::string,ll>::iterator itr;
itr=m.find(str);
if(itr!=m.end()){
count+=(itr->second)/2;
}
else{
ll num = str.size();
ll temp = FindCount(str.c_str(),num);
count+=temp;
m.insert({str,temp});
}
}
std::cout<<count<<"\n";
}
return 0;
}
The link to the problem statement is: https://www.codechef.com/SDPCB21/problems/TYPING
I am getting an infinite number of '0' as output each on new line.
Please tell me if there is any logical error or error of any kind in the code.
Thankyou.

Vector error,a very confusing segmentation error?

So basically,I am doing a code which searches for an element of a vector inside a vector.While I thought of the approach , implementing it got me a segmentation error. I narrowed down the problem
In the code if I decomment the line in the for loop while commenting the above then all elements of B[i] are being displayed.Why then is a segmentation error being thrown. I think the binary_return is more or less correct and if I replace the line with
binary_return(A,0,A.size(),B[1])
then its working.
Here is the code:
#include<iostream>
#include<vector>
using namespace std;
int binary_return(vector<int> a,int start,int end,int seek)
{
int mid = (start+end)/2;
//cout<<start<<" "<<seek<<" "<<mid;
if(end!=start)
{
if(a[mid]==seek)
{
return mid;
}
else if(a[mid]>seek)
{
return binary_return(a,start,mid,seek);
}
else if(a[mid]<seek)
{
return binary_return(a,mid,end,seek);
}
}
else
return -1;
}
int main()
{
vector<int> A{1,3,6,9,23};
vector<int> B{1,4,23};
cout<<B[0]<<B[1]<<B[2];
for(int i=0;i<B.size();i++)
{
cout<<binary_return(A,0,A.size(),B[i]);
//cout<<binary_return(A,0,A.size(),B[0]);
}
return 1;
}
Your code is not handling the last case correctly and ends up in infinite recursion.
This unfortunately in C++ means that anything can happen (you're not guaranteed to get a meaningful error).
Add a debug print at the beginning of the function and you'll see in which cases you're entering infinite recursion.
You have infinite recursion in third if statment
The correct code if the following:
#include<iostream>
#include<vector>
using namespace std;
int binary_return(vector<int> a,int start,int end,int seek)
{
int mid = (start+end)/2;
//cout<<start<<" "<<seek<<" "<<mid;
if(end!=start)
{
if(a[mid]==seek)
{
return mid;
}
else if(a[mid]>seek)
{
return binary_return(a,start,mid,seek);
}
else if(a[mid]<seek)
{
// In your sample you forgot to add +1 (mid+1) for next start
return binary_return(a,mid+1,end,seek);
}
}
else
return -1;
}
int main()
{
vector<int> A{1,3,6,9,23};
vector<int> B{1,4,23};
for(int i=0;i<B.size();i++)
{
cout<<binary_return(A,0,A.size(),B[i]);
}
return 0;
}

How Can I Solve My Dynamic Programming Problem?

Here is my code:
#include<bits/stdc++.h>
using namespace std;
typedef long long int lli;
#define M 1000000007
#define INF 1000000007
typedef pair<lli,lli> ll;
#define mem(a,x) memset(a,x,sizeof(a))
lli n,k,m;
lli dist[507][507];
lli path1[207][207];
vector<int> v2(1005,1);
vector<double> v;
lli x,y,c,z,t,q,u,d,a1,b;
struct edge
{
lli a,b,cost;
};
/*void djkstra(int x,vector<ll> v[])
{
mem(vis,0);
dist[x]=0;
s2.insert({0,x});
while(!s2.empty())
{
ll p=*s2.begin();
s2.erase(s2.begin());
x=p.second;
if(vis[x])
continue;
vis[x]=1;
for(int j=0;j<v[x].size();j++)
{
if(dist[v[x][j].second]>dist[x]+v[x][j].first)
{
dist[v[x][j].second]=dist[x]+v[x][j].first;
s2.insert({dist[v[x][j].second],v[x][j].second});
a[v[x][j].second]=x;
}
}
}
}*/
lli parent[100007];
lli find(lli a)
{
return a==parent[a]?a:parent[a]=find(parent[a]);
}
void dset(lli n)
{
for(int j=0;j<=n;j++)
parent[j]=j;
}
void unio(lli a,lli b,lli rank[])
{
if(rank[find(a)]>rank[find(b)])
parent[find(b)]=find(a);
else if(rank[find(b)]>rank[find(a)])
parent[find(a)]=find(b);
else
{
parent[find(a)]=find(b);
rank[find(b)]++;
}
}
bool check(lli a)
{
if((a1*a*m+b*(a-1)+d)>=x)
return true;
return false;
}
/*bool valid(int i,int x)
{
for(int j=1;j<x;j++)
{
if((abs(b[j-1]-i)==abs(j-x))||(i==b[j-1])||(j==x))
return false;
}
return true;
}*/
lli p[10007];
lli dp[301][301][301];
map<ll,ll> pat;
map<ll,lli> p2;
lli pr[200007],we[200007];
lli a[100005];
map<lli,lli> m4;
vector<int> v4;
int f=0;
lli tot=1;
lli vis[1001][1001];
lli p1;
lli s[10001];
lli n1;
lli solve(lli n,lli i,lli c)
{
//cout<<n<<" "<<i<<" "<<a[i]<<" "<<dp[n][i]<<endl;
if(i>n1)
return 0;
if(c==0&&n>0)
return 0;
if(c==0&&n==0)
return 1;
if(n<0)
return 0;
if(dp[n][i][c]!=-1)
return dp[n][i][c];
dp[n][i][c]=solve(n-i,i,c-1);
dp[n][i][c]+=solve(n,i+1,c);
return dp[n][i][c];
}
int main()
{
while(1)
{
string s="\0";
getline(cin,s);
if(s.size()==0)
return 0;
string d[3];
d[0]="\0";
d[1]="\0";
d[2]="\0";
int c=0;
for(int i=0;i<=300;i++)
{
for(int j=1;j<=300;j++)
{
for(int k=1;k<=300;k++)
dp[i][j][k]=-1;
}
}
for(int j=0;j<s.length();j++)
{
if(s[j]!=' ')
d[c]+=s[j];
else
c++;
}
int f;
stringstream ss(d[0]);
ss>>f;
n1=f;
lli d1=0;
for(int i=1;i<=f;i++)
d1+=solve(f,1,i);
for(int i=0;i<=300;i++)
{
for(int j=0;j<=300;j++)
dp[0][i][j]=1;
}
lli sum[f+1];
mem(sum,0);
sum[0]=1;
for(int i=1;i<=f;i++)
{
if(i==1)
sum[i]=dp[f][1][i];
else
sum[i]=sum[i-1]+dp[f][1][i];
}
if(c==0)
{
if(f!=0)
cout<<d1<<endl;
else
cout<<1<<endl;
}
else if(c==1)
{
int f1;
stringstream ss1(d[1]);
ss1>>f1;
if(f1>f)
f1=f;
cout<<sum[f1]<<endl;
}
else
{
int f1,f2;
stringstream ss1(d[1]);
ss1>>f1;
stringstream ss2(d[2]);
ss2>>f2;
if(f1>f)
cout<<0<<endl;
else
{
if(f2>f)
f2=f;
cout<<sum[f2]-sum[f1]+dp[f][1][f1]<<endl;
}
}
}
}
In the following function:
lli solve(lli n,lli i,lli c)
My solution is O(N^3), and it should pass the test cases (N=300), but still time limit exceeds for it.
How can I solve this problem?
Here is the problem link.
Ok so the point the dynamic programming is being able to reuse what was already done.
So how to reuse your code?
Here's my idea:
let say the total amount is 6$ and we know we have a total of 3 pieces maximum totalize that amount. You can begin to try by beginning with by finding the way to make a total of 1$, than 2$, 3$, .. alway reusing what you done before.
Example
1 $ total
only way 1x1$ (keep that in memory)
2 $ total
-decompose in all possible 2 pieces you can add: 1+1, 2
-to find other possibilities, reuse what you done before recursivly (the recursion at this level stops after only the first iteration because 1$ is the minimum dollar value)
-keep that in memory
... (continue like that with 3 $ total, 4 $ total, 5$ total ...)
6$ total
-decompose in all possible 2 pieces you can add: 6, 1+5, 2+4 3+3 (always (n intDiv 2) +1 possibilities) possibilites
-to find other possibilities, reuse what you done before recursivly:
example: for the 3+3 possibility, go look at all the possibilities found at 3$ total to find all possibilities.
- Remove all possibilites that used too much pieces.
You finished by finding all possibilities as an answer: 1+1+4, 1+2+3, 3+3 and 2+2+2.
Hope it helps :)

Newton Raphson for Cube Root (Precision Error in Double)

I am trying to implement Newton Raphson in C++.
Approach: In my root() function my while(temp-e>0) exists even when temp==e. I know it is due to using doubles and comparing double might give precision errors sometimes. But still I want to know how can I make sure that the loop exists only when temp==0. Error occurring in the test case 64. My code is returning 4.000001, while it should return 4.000000.
Code:
#include<stdio.h>
double root(int n)
{
double x=n,a,b,e=0.000001,temp;
a=2*x;
b=n/(x*x);
temp=1;
while(temp-e>0)
{
x=(a+b)/3;
a=2*x;
b=n/(x*x);
temp=(n/(x*x)-x)/3;
temp=temp<0?-temp:temp;
}
return x;
}
int main()
{
printf("%lf\n",root(64));
return 0;
}
While this code is giving correct answer, where I am doing two more iterations from where temp starts failing:
#include<stdio.h>
double root(int n)
{
double x=n,a,b,e=0.000001,temp;
a=2*x;
b=n/(x*x);
int i=0;
temp=1;
while(i<=2)
{
x=(a+b)/3;
a=2*x;
b=n/(x*x);
temp=(n/(x*x)-x)/3;
temp=temp<0?-temp:temp;
if(temp<e)
i++;
}
return x;
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
printf("%lf\n",root(n));
}
return 0;
}

Binary Search with few modification

While I am trying to compile the code with few modification in binary search recursive function. The program is acting weird. Some time it gives the correct value and some time it goes to infinite loop. Please explain what went wrong with the code. I am using DEV C++ as an IDE.
CODE:
#include<iostream>
#include<sstream>
using namespace std;
//function to compare the two integers
int compare(int low, int high)
{
if (low==high)
return 0;
if (low<high)
return 1;
else
return -1;
}
//Function for binary search using recursion
int *BinarySearch(int *Arr,int Val,int start,int end)
{
int localstart=start;
int localend=end;
int mid=(start+end)/3;
cout<<"MID:"<<mid;
int comp= compare(Val,Arr[mid]);
if(comp==0)
return &(Arr[mid]);
else if (comp>0)
return BinarySearch(Arr,Val,localstart,mid-1);
else
return BinarySearch(Arr,Val,mid+1,localend);
return NULL;
}
main()
{
int *arr;
arr= new int [256];
string str;
getline(cin,str);
stringstream ss;
ss<<str;
int index=0;
while(ss>>arr[index])
{index++;}
//cout<<arr[index-1];
cout<<"Enter Value:";
int value;
cin>>value;
int *final;
final=BinarySearch(arr,value,0,index-1);
if(final!=NULL)
cout<<"Final:"<<*final;
else
cout<<"Not Found";
getchar();
getchar();
return 0;
}
Two ideas:
What should BinarySearch do if Val is not in the array? Trace out what your code does in this case.
(start+end)/3 probably isn't the middle of the current range.