An Interesting Compile-Error on Topcoder - c++

This code gives a compile-error on Topcoder. On code::blocks, it compiles with 0 errors and 0 warnings, the vector is printed, but it exits with a non-zero value, that causes windows to display "InterestingDigits.exe has stopped working". Any help on this..?
#include<iostream>
#include<vector>
using namespace std;
class InterestingDigits
{
public:
vector <int> digits(int base)
{
vector<int> v;
for(int i=2; i<base; i++)
if(base%i==1)
v.push_back(i);
for(int i=0; i<v.size(); ++i)
cout<<v[i]<<" ";
cout<<endl;
}
};
int main()
{
int base;
cin>>base;
InterestingDigits id;
id.digits(base);
return 0;
}

It seems that your method digits() should return a value, a vector < int >.
Maybe adding a "return v;" at the end?

You need to return a vector. With your code, compiler would try to return something that caused the undefined behaviour. So adding "return v" should fix your issue.

Related

Why am I not able to input anything?

I think I've written correct code but I am not able to input anything. Please help me.
Question - https://codeforces.com/problemset/problem/25/A
My code-
#include<iostream>
using namespace std;
int main(){
int n,count(0);
int arr[n];
for(int i=0;i<n;++i){
cin>>arr[i];
}
for(int i=2; i<n; ++i){
if(arr[i]-arr[i-1] != arr[i-1]-arr[i-2]){
++count;
}
}
cout<<count<<endl;
return 0;
}
It's probably undefined behavior from your int n variable being uninitialized. Initializing n to an explicit value allows for input as intended.

In c++ code, set.erase(it) is halting execution, where it=set.begin() for a set of pairs, why is this happening?

Sorry for any inconvenience I am a beginner at C++ and was stuck with an empty set... Thank you for the helpful comments that helped me figure out what the problem was
I wrote a C++ code for a question in which I need to use Dijkstra's shortest path algorithm in n*log(n) time and so I am using set of pairs to obtain the vertex with shortest distance from source vertex. The code was not giving any errors at runtime but it wasn't giving the output either. So to see where it was getting stuck I used cout statements at certain points in the code and figured that the code is stopping execution right after the erase statement.
The statement is used in the code for erasing the first pair in the set and so the iterator pointing to set.begin() of the set is given as argument. It was earlier written in the format set.erase(iterator), but after searching for this problem on stack overflow I found someone saying iterator=set.erase(iterator) will solve the problem. I tried that and it still was getting stuck at that line, neither stopping execution and returning to the terminal nor giving a runtime error. I don't know what is wrong with this so I thought I would get some help here.
I am providing my code and a screenshot of the running too I would really appreciate your help.
#include<bits/stdc++.h>
using namespace std;
# define _z ios_base::sync_with_stdio(false); cin.tie(NULL);
# define ll long long int
#define mod 1000000007
int n;
set<pair<int, int>> dist;
void dij(vector<pair<int, int>> tree[], int decided[], int d[], vector<int>path[]) {
int mindist=INT_MAX, ind=0;
auto it=dist.begin();
ind=it->second;
cout<<"inbetween"<<endl;
dist.erase(it);
cout<<"inbetween"<<endl;
decided[ind]=1;
for(int i=0; i<tree[ind].size(); i++) {
int update=d[ind]+tree[ind][i].second;
int previous=d[tree[ind][i].first];
if(update<previous) {
pair<int, int>p=make_pair(previous, tree[ind][i].first);
dist.erase(dist.find(p));
p=make_pair(update, tree[ind][i].first);
dist.insert(p);
path[tree[ind][i].first]=path[ind];
cout<<*path[tree[ind][i].first].begin()<<endl;
path[tree[ind][i].first].push_back(tree[ind][i].first);
}
d[tree[ind][i].first]=min(update, previous);
}
}
int main()
{
int edges;
cin>>n>>edges;
vector<pair<int, int>> graph[n];
set<pair<int, int>> dist;
for(int i=0; i<edges; i++) {
int x, y, weight;
cin>>x>>y>>weight;
x--; y--;
graph[x].push_back({y, weight});
graph[y].push_back({x, weight});
}
int src=1;
//cin>>src;
cout<<"here"<<endl;
src--;
int d[n];
for(int i=0; i<n; i++) {
if(src==i) {
dist.insert({0, i});
d[i]=0;
}
else {
dist.insert({INT_MAX, i});
d[i]=INT_MAX;
}
}
int decided[n]={0};
vector<int> path[n];
path[src].push_back(src);
for(int i=0; i<n; i++) dij(graph, decided, d, path);
if(path[n-1].begin()==path[n-1].end()) cout<<-1<<endl;
for(auto it=path[n-1].begin(); it!=path[n-1].end(); it++) cout<<*it+1<<" ";
cout<<endl;
}
Image of the running code: Note that the highlighted lines are the problematic ones neither does iterator manipulation exist in the part of code that is getting stuck nor is the iterator accessed again after erasing.
It is only printing the line before the erase statement and not printing the one after...
The problem as told by user4581301 in the comments was that the iterator was pointing to the end() of the set, which means the set was empty as it was initialized to point to begin() of the set. Thus an undereferencable iterator was dereferenced resulting in undefined behavior, (this means it may not necessarily give a runtime error but rather provide an output when dereferenced). Although the program thus gets stuck at this line as a result of this invalid accessing.
The fault in the code was that set was defined globally but then was refined by the same name inside main, this meant when the values are filled in the set inside main, they are filled in the set that was defined within main not the one defined globally. But when accessing the set in the function dij, the global set is accessed which is actually empty!
Removing the redefinition in main would resolve the issue.
#include<bits/stdc++.h>
using namespace std;
# define _z ios_base::sync_with_stdio(false); cin.tie(NULL);
# define ll long long int
#define mod 1000000007
int n;
set<pair<int, int>> dist;
void dij(vector<pair<int, int>> tree[], int decided[], int d[], vector<int>path[]) {
int mindist=INT_MAX, ind=0;
auto it=dist.begin();
if(it==dist.end()) return;
ind=it->second;
dist.erase(it);
decided[ind]=1;
for(int i=0; i<tree[ind].size(); i++) {
int update=d[ind]+tree[ind][i].second;
int previous=d[tree[ind][i].first];
if(update<previous) {
pair<int, int>p=make_pair(previous, tree[ind][i].first);
dist.erase(dist.find(p));
p=make_pair(update, tree[ind][i].first);
dist.insert(p);
path[tree[ind][i].first]=path[ind];
path[tree[ind][i].first].push_back(tree[ind][i].first);
}
d[tree[ind][i].first]=min(update, previous);
}
}
int main()
{
int edges;
cin>>n>>edges;
vector<pair<int, int>> graph[n];
for(int i=0; i<edges; i++) {
int x, y, weight;
cin>>x>>y>>weight;
x--; y--;
graph[x].push_back({y, weight});
graph[y].push_back({x, weight});
}
int src=1;
src--;
int d[n];
for(int i=0; i<n; i++) {
if(src==i) {
dist.insert({0, i});
d[i]=0;
}
else {
dist.insert({INT_MAX, i});
d[i]=INT_MAX;
}
}
int decided[n]={0};
vector<int> path[n];
path[src].push_back(src);
for(int i=0; i<n; i++) dij(graph, decided, d, path);
if(path[n-1].begin()==path[n-1].end()) cout<<-1<<endl;
for(auto it=path[n-1].begin(); it!=path[n-1].end(); it++) cout<<*it+1<<" ";
cout<<endl;
}
The above code thus works perfectly fine. Below is the screenshot of the working code's output:
Here are some of the links provided in the comments that helped:
https://en.cppreference.com/w/cpp/language/ub (undefined behaviour)
https://ideone.com/5NY0q3 (code that proved begin is pointing to end)
https://en.cppreference.com/w/cpp/container/vector/erase (about erase)
https://codeforces.com/contest/20/problem/C (problem statement that the code pertains to)
P.S. The code finds the path through which the shortest distance between vertex 1 and vertex n of a graph with weighted edges can be obtained, in O(n*log(n)).
Thank you.

Why am I not getting any output(linear search)?

#include<iostream>
using namespace std;
int main(){
int n;
int current_element;
cin>>n>>current_element;
int arr[n];
for(int i=0;i<n;i++){
cin>>arr[i];
}
int i;
for(i=n-1;i<=0;--i){
if(current_element==arr[i]){
cout<<i;
}
else{
cout<<"-1";
}
}
}
I was trying to do linear search program but there was no output, what is wrong in the code?
I think the problem is that you declared " i " twice and that has no sense. Here is the right code:
#include<iostream>
using namespace std;
int main(){
int n, i=0;
int current_element;
cin>>n>>current_element;
int arr[n];
for(i=0;i<n;i++){
cin>>arr[i];
}
for(i=n-1;i<=0;--i){
if(current_element==arr[i]){
cout<<i;
}
else{
cout<<"-1";
}
}
}
This way you initialize " i " once with the value of 0 and it should work.
i think its because in your for loop you said
for(int i = n-1; i <= 0; --i)
this doesnt seem like what you are trying to do as it says that it will keep running as long as i<=0 however i is never less than or equal to zero. i think you would want to write i>=0 instead. also, you have 2 "i" variables which you initialized.
It seems that you made a mistake on the second loop clause.
Your code
...
//loop condition is causing the problem
for(i=n-1;i<=0;--i){
...
Fixed code
...
//loop condition is causing the problem
for(i=n-1;i>=0;--i){
...
The loop condition causes the program to not enter the second for loop. Modifying it makes the program work.
Full code
#include<iostream>
using namespace std;
int main(){
int n;
int current_element;
cin>>n>>current_element;
int arr[n];
for(int i=0;i<n;i++){
cin>>arr[i];
}
int i;
//loop condition is causing the problem
for(i=n-1;i>=0;--i){
if(current_element==arr[i]){
cout<<i;
}
else{
cout<<"-1";
}
}
}

Method defined in class doesn't return anything when called in main

I don't understand why twoSum method inside the Solution class does not output anything when called in main. Please tell me why. The program should output the positions of two numbers that are together equal to target variable. There is only one valid set with this property. You can find this problem on leetcode:
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
#include <iostream>
#include<vector>
#include<map>
using std::vector;
using std::map;
class Solution {
public:
vector <int> twoSum(vector<int>& nums, int target) {
map <int,int> mymap;
vector <int> res;
for(int i=0; i<nums.size(); i++)
{
mymap[nums[i]]=i;
}
for(int i=0; i<nums.size(); i++)
{
int result = target - nums[i];
if(mymap.find(result)!=mymap.end() && mymap[result] != i)
{
res.push_back(i);
res.push_back(mymap[result]);
return res;
}
}
return res;
}
};
int main()
{
vector<int> nums(4);
int target;
for(int i=0;i<4;i++)
{
std:: cin>> nums[i];
std:: cout<<nums[i]<<' ';
}
std:: cin>>target;
Solution abc;
abc.twoSum(nums,target);
return 0;
}
///For array=[1,2,3,4] and target= 6, i expected the output to be [1,3]. Instead it doesn't print out anything
You're confusing "output" as in "something printed on the console", and "output" as in "a value returned by a function".
The abc.twoSum(nums,target); call in main returns a vector of ints. In C and C++ return values may be ignored and then are simply lost.
If you want something to be printed you have to store the return value of the function in a variable or use it directly and then actually print it.

Why is IDEone showing runtime error even after getting the output?

What is wrong with my program ?
It works fine on my PC but in IDEone it gives the correct output but shows runtime error. Please help.
#include<bits/stdc++.h>
using namespace std;
struct student
{
int vote;
};
int main()
{
int t;
cin>>t;
while(t--)
{
int count=0;
int n;
cin>>n;
vector <int> a(n);
student s[n];
int k;
cin>>k;
for(int i=1;i<=n;i++)
{
s[i].vote=0;
}
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
int temp=0;
for(int i=1;i<=n;i++)
{
if(a[i] != i)
{
temp=a[i];
s[temp].vote++;
}
}
for(int i=1;i<=n;i++)
{
if(s[i].vote==k)
{
count++;
}
}
printf("%d\n",count);
}
return 0;
}
This is the error shown in IDEone :-
Error in `./prog': free(): invalid next size (fast): 0x085cca10
student s[n];
This declares an array called s. It contains n values. The values are s[0] through s[n-1] (you can count them all on your fingers, if you'd like, using a small number of n, such as 5).
for(int i=1;i<=n;i++)
{
s[i].vote=0;
}
This attempts to initialize values s[1] through s[n]. The only problem is that s[n] doesn't exist. The last value in the array is s[n-1]. This code will corrupt memory on the stack, resulting in undefined behavior.
The same bug also occurs with the a array.
The index values for both vector and array are zero based and goes up to n - 1. So
for(int i = 0; i != n; ++i)
would be better.
Now you write one element too far, which free finds out later when the data after the memory block is invalid.