Why this code gives WA for Petersen Graph(codechef)? - algorithm
I tried to solve Petersen Graph question without any success. What's wrong with this code? You may say that this is not an efficient solution, it's ok. Here I am, doing DFS for given graph.
sruct ss holds a graph. Each String is saved in a Set and whenever recursion terminates an output is produced. I'm not able find the test case where this approach is failing. Can you give me a test case where this approach will fail?
#include<bits/stdc++.h>
using namespace std;
struct ss{
int p;
int a[3];
char s[3];
};
string get(int k){
switch(k){
case 0:return "0";
case 1:return "1";
case 2:return "2";
case 3:return "3";
case 4:return "4";
case 5:return "5";
case 6:return "6";
case 7:return "7";
case 8:return "8";
case 9:return "9";
}
}
void traverse(string s,ss z[10],int index, set<string> &s1,string s2,int v){
int p = s[index]-'A',i,j;
if(v!=-1)s2 +=get(v);
if(!s[index]){
s1.insert(s2);
return;
}
if(v==-1){
traverse(s,z,index+1,s1,s2,z[2*p].p);
traverse(s,z,index+1,s1,s2,z[2*p+1].p);
}
else{
if(v>=5){v = v-5;v = 2*v+1;}
for(i=0;i<3;i++){
if(z[v].s[i]==s[index]){
traverse(s,z,index+1,s1,s2,z[v].a[i]);
break;
}
}
for(j=0;j<3;j++){
if(z[v].s[j]==s[index]){
traverse(s,z,index+1,s1,s2,z[v].a[j]);
break;
}
}
}
}
int main(){
string s;
set<string> s1;
int t;
ss z[ ]={
{0,{1,4,5},{'B','E','A'}},
{5,{0,7,8},{'A','C','D'}},
{1,{0,2,6},{'A','C','B'}},
{6,{1,8,9},{'B','D','E'}},
{2,{1,3,7},{'B','D','C'}},
{7,{2,5,9},{'C','A','E'}},
{3,{2,4,8},{'C','E','D'}},
{8,{3,5,6},{'D','A','B'}},
{4,{0,3,9},{'A','D','E'}},
{9,{4,6,7},{'E','B','C'}}
};
cin>>t;
while(t--){
s1.clear();
cin>>s;
traverse(s,z,0,s1,"",-1);
if(s1.end()==s1.begin()){
cout<<-1<<"\n";
}
else
cout<<*s1.begin()<<"\n";
}
}
The code fails almost every test case I tried. I think the problem is in traverse, in the if statement conditions within the for loops (lines 45 and 51).
if(z[v].s[i]==s[index])
Here, you want index x, such that z[x].p is equal to v. v is not always the correct index, so z[v] is incorrect. Likewise in the other line. Try test cases 'EE' and 'ABCD'.
It would be easiest to reorder the Z array in the order of Z[i].p values, I think.
Related
How can I remove the segmentation error in the following code?
In the following code, I am getting the segmentation fault. Whenever the query type is 1, we have to push element into the stack, if it is 2 then we have to pop from stack, and if it is 3 then print the maximum value in the stack. My guess is that the error is present somewhere in the switch case. However, I am unable to spot it. Please help. #include<bits/stdc++.h> using namespace std; int maxinStack(stack<int> st){ int max=st.top(); for (int i=0;i<st.size();i++){ if(st.top()>max){ max=st.top(); } st.pop(); } return max; } int main() { /* Enter your code here. Read input from STDIN. Print output to STDOUT */ stack<int> s; int querySize; cin >> querySize; vector<int> queryType(querySize); queue<int> queryData; for(int i=0;i<querySize;i++){ cin>>queryType[i]; if(queryType[i]==1){ int x; cin >> x; queryData.push(x); } } /*for (int j=0;j<querySize;j++){ cout << queryType.at(j)<<" "; } cout << endl; while(!queryData.empty()){ cout << queryData.front()<<" "; queryData.pop(); } cout << endl; */ for (int j=0;j<querySize;j++){ switch (queryType[j]){ case 1:{ int y=queryData.front(); s.push(y); queryData.pop(); } case 2: s.pop(); case 3: cout << maxinStack(s)<<endl; } } return 0; }
Assuming inputs are correct, I think you forgot to put break at the end of each case handlers. So it should be something like: switch (queryType[j]){ case 1:{ int y=queryData.front(); s.push(y); queryData.pop(); break; } case 2: s.pop(); break; case 3: cout << maxinStack(s)<<endl; break; } Otherwise when it handles case 1 it will still fall-through to the next case handlers so it also does case 2 and case 3. This means that the stack is always empty and it causes segmentation fault when it handles query type of 2 - tried to pop for an empty stack.
As pointed above by #Hanjoung, your switch cases are missing break statements. Just to give you a little context on these break statements, if not specified all the cases after the matched case will also run. For eg: switch(choice){ case 1: case 2: // Suppose this case matched case 3: // This will also run as no break in case 2 break; case 4: // Will not run as break in case 3 default: } The reason you are getting segmentation error is because your "case 2" is popping from empty stack, and reason for running of this "case 2" is absence of break statement in "case 1".
How to rewrite "node->left->key" replacing -> with "(*)." in C++?
I'm new to the "->" symbol, so I'm instead replacing it with (*). . However, when I came across the line of code below, I tried replacing it and it didn't work. What am I doing wrong and is there any way to rewrite it? I keep getting the error that "key" is a pointer and when I rewrite it, it doesn't work. I have triple checked my code, and yet I still don't understand. struct Node{ int key; Node *left; Node *right; }; Node* createNode(int key){ Node *node = new Node(); (*node).key = key; (*node).left = NULL; (*node).right = NULL; return node; } int main(){ Node *root = createNode(1); (*root).left = createNode(9); cout << root->left->key; // Correct? cout << " OR "; cout << ((*root).left).(*key); // this is where my code goes wrong and if I remove the (*) from key // and just leave it like .key it's wrong because key has to be a pointer return 0; } I expect the output to be "9 OR 9" but it doesn't even let me compile past that point.
If you really want to avoid the -> operator, you can write it like this: cout << (*((*root).left)).key; ... but that's painful to write and painful to read, so it makes a great example of why the -> operator is useful :)
scanf,fgets, fgetc get skipped inside loop
Im trying to make a recursive menu. This program will later work with a tree(hojanodo), thats why I keep track of the root. Problem: For some reason the fgets/fgetc is being skipped inside the recursivity on the second run, why does this happen? I want the user to input either 1,2 or 3.(int) What would be the fix for this? and is this the best way to implement a menu? Here's what I have right now:(It compiles and runs so you can test it out but doesn't really work like I would like to..) #include<stdio.h> #include<stdlib.h> typedef struct node{ char ch; int i; struct node *left; struct node *right; }hojaNodo; int handle_menu(int eventHandler, hojaNodo **root); int opcion_menu(); char get_symbol(); int get_userMenuInput(); int intro(); int main(){ hojaNodo *treeRoot = NULL; intro(); // system("clear"); handle_menu(opcion_menu(), &treeRoot); return 0; } int opcion_menu(){ int userOption; printf("1.Agrega un Simbolo.\n"); printf("2.Listar Codigo\n"); printf("3.Exit"); userOption = get_userMenuInput(); printf("User: %d",userOption); if(userOption < 4 && userOption > 0){ return userOption; } else return -1; }//eof opcion_menu int handle_menu(int userOption,hojaNodo **root){ hojaNodo *tempRoot = NULL; tempRoot = *root; int valor; char simbol; switch(userOption){ case 1: simbol = get_symbol(); printf("Simbol: %c", simbol); break; case 2: printf("List Nodes\n"); break; case 3: printf("Exit"); userOption = -1; // destroy_tree(root); break; default: printf("userOption Error, Bye!"); break; }//eof switch if(userOption != -1) handle_menu(opcion_menu(),&tempRoot); // return userOption; return -1; }//eof menu() char get_symbol(){ /*char userKey[3] fgets(userKey,len,stdin);*/ char simbolo; printf("Give me a symbol."); simbolo = fgetc(stdin); return simbolo; } int get_userMenuInput(){ char userKey[3]; int userOption; size_t len; len = sizeof(userKey); fgets(userKey,len,stdin); userOption = atoi(userKey); //printf("User Option: %d\n", userOption); return userOption; }
Well apart from all the comments related to recursion and other changes suggested, please check this out. fgets() function needs flushing the input stream. It can be done using fflush() or fgetc(). A simple solution would be: In function: int opcion_menu(){ ... fgets(userKey,2,stdin); fgetc(stdin); // Add this statement Also in function: int handle_menu(int userOption,hojaNodo **root) case 1: printf("Give me a choice : "); fgets(userKey,2,stdin); fgetc(stdin); // add this statement fgets reads in at most one less than size characters from stream and stores them into the buffer pointed to by string. This will lead the newline character still available in Input Stream which need to be flushed. If this newline character is not read from Input stream, than this would become the input for next fgets function and ultimately it will skip the fgets(since it has already got its input a newline character) fgetc(stdin) will flush out these extra newline character.
I don't know if this might help anyone. In my case, I had to 'free' the buffer from the char with this function: void clean(){ char cTemp; while((cTemp = getchar()) != '\n') ; } Im not really sure why this works but it does(if anyone does, please add it to my answer). I call it right before I call get_userOption();
STXXL: limited parallelism during sorting?
I populate a very large array using a stxxl::VECTOR_GENERATOR<MyData>::result::bufwriter_type (something like 100M entries) which I need to sort in parallel. I use the stxxl::sort(vector->begin(), vector->end(), cmp(), memoryAmount) method, which in theory should do what I need: sort the elements very efficiently. However, during the execution of this method I noticed that only one processor is fully utilised, and all the other cores are quite idle (I suspect there is little activity to fetch the input, but in practice they don't do anything). This is my question: is it possible to exploit more cores during the sorting phase, or is the parallelism used only to fetch the input asynchronously? If so, are there documents that explain how to enable it? (I looked extensively the documentation on the website, but I couldn't find anything). Thanks very much! EDIT Thanks for the suggestion. I provide below some more information. First of all I use MacOs for my experiments. What I do is that I launch the following program and I study its behaviour. typedef struct Triple { long t1, t2, t3; Triple(long s, long p, long o) { this->t1 = s; this->t2 = p; this->t3 = o; } Triple() { t1 = t2 = t3 = 0; } } Triple; const Triple minv(std::numeric_limits<long>::min(), std::numeric_limits<long>::min(), std::numeric_limits<long>::min()); const Triple maxv(std::numeric_limits<long>::max(), std::numeric_limits<long>::max(), std::numeric_limits<long>::max()); struct cmp: std::less<Triple> { bool operator ()(const Triple& a, const Triple& b) const { if (a.t1 < b.t1) { return true; } else if (a.t1 == b.t1) { if (a.t2 < b.t2) { return true; } else if (a.t2 == b.t2) { return a.t3 < b.t3; } } return false; } Triple min_value() const { return minv; } Triple max_value() const { return maxv; } }; typedef stxxl::VECTOR_GENERATOR<Triple>::result vector_type; int main(int argc, const char** argv) { vector_type vector; vector_type::bufwriter_type writer(vector); for (int i = 0; i < 1000000000; ++i) { if (i % 10000000 == 0) std::cout << "Inserting element " << i << std::endl; Triple t; t.t1 = rand(); t.t2 = rand(); t.t3 = rand(); writer << t; } writer.finish(); //Sort the vector stxxl::sort(vector.begin(), vector.end(), cmp(), 1024*1024*1024); std::cout << vector.size() << std::endl; } Indeed there seems to be only one or maximum two threads working during the execution of this program. Notice that the machine has only a single disk. Can you please confirm me whether the parallelism work on macos? If not, then I will try to use linux to see what happens. Or is perhaps because there is only one disk?
In principle what you are doing should work out-of-the-box. With everything working you should see all cores doing processing. Since it doesnt work, we'll have to find the error, and debugging why we see no parallel speedups is still tricky business these days. The main idea is to go from small to large examples: what platform is this? There is no parallelism on MSVC, only on Linux/gcc. By default STXXL builds on Linux/gcc with USE_GNU_PARALLEL. you can turn it off to see if it has an effect. Try reproducing the example values shown in http://stxxl.sourceforge.net/tags/master/stxxl_tool.html - with and without USE_GNU_PARALLEL See if just in memory parallel sorting scales on your processor/system.
Having trouble implementing a linked list in c++
I am trying to implement a simple singly linked list of integers which are to be sorted upon insertion in Visual Studio c++ 2010 express. The problem is that when I create a new node and call the .getValue() function on it, the correct number is returned, however somehow that is being lost when I try calling getValue() on a node already in the list. The node might not be inserted into the list correctly, however I can't find why that would be the case. Some other value which looks like a reference value or something is displayed instead of the correct value. I added current to the watch window when debugging but was still unable to see any of my variables other than the give value to be inserted. I am new to visual studio so I'm not sure if I'm missing something there. Here is my code: #include "Node.h"; #include <iostream> //namespace Linked{ //The first two constructors would be the first in the linked list. Node::Node(void){ value = 0; next = 0; } Node::Node(int setValue){ value = setValue; next = 0; } Node::Node(int setValue,Node *nextNode){ value = setValue; next = nextNode; } Node * Node::getNext(){ return next; } void Node::setNext(Node newNext){ next = &newNext; } int Node::getValue(){ return value; } bool Node::isEqual(Node check){ return value==check.getValue()&&next == check.getNext(); } /* int main(){ int firstInt, secondInt; std::cin>>firstInt; Node first = Node(firstInt); std::cout<<"Enter second int: "; std::cin>>secondInt; Node second = Node(secondInt, &first); std::cout<<"Second: "<<second.getValue()<<"\nFirst: "<<(*second.getNext()).getValue(); system("pause"); }*/ Here is the linked list: //LinkedList.cpp LinkedList::LinkedList(void) { head = 0; size = 0; } LinkedList::LinkedList(int value) { head = &Node(value); size = 1; } void LinkedList::insert(int value){ if(head == 0){ Node newNode = Node(value); head = &newNode; std::cout<<"Adding "<<(*head).getValue()<<" as head.\n"; }else{ std::cout<<"Adding "; Node current = *head; int numChecked = 0; while(size<=numChecked && (((*current.getNext()).getValue())<value)){ current = (*(current.getNext())); numChecked++; } if(current.isEqual(*head)&¤t.getValue()<value){ Node newNode = Node(value, ¤t); std::cout<<newNode.getValue()<<" before the head: "<<current.getValue()<<"\n"; }else{ Node newNode = Node(value,current.getNext()); current.setNext(newNode); std::cout<<newNode.getValue()<<" after "<<current.getValue()<<"\n"; } } size++; } void LinkedList::remove(int){ } void LinkedList::print(){ Node current = *head; std::cout<<current.getValue()<<" is the head"; int numPrinted = 0; while(numPrinted<(size-1)){ std::cout<<(current.getValue())<<", "; current = (*(current.getNext())); numPrinted++; } } int main(){ int a[5] = {30,20,25,13,2}; LinkedList myList = LinkedList(); int i; for(i = 0 ; i<5 ; i++){ myList.insert(a[i]); } myList.print(); system("pause"); } Any guidance would be greatly appreciated!
When you create nodes in insert, you're allocating them off the stack, which means that they'll be lost after the function returns. Get them off the heap with: Node * newNode=new Node(value); When you use: Node newNode=Node(value); You're allocating that object on the stack, which means that pointers: &newNode to it are only valid until that function returns. If you use heap memory this is no longer an issue, but it does mean that you have to implement a destructor for your list which goes through and deletes each node.