Is there any way to speedup the graph based solution to this CodeJam problem?

Правка en1, от codex666, 2021-03-22 19:42:34

Dear Brethren, I was trying out this Google CodeJam 2019 round 1A problem PYLON, https://codingcompetitions.withgoogle.com/codejam/round/0000000000051635/0000000000104e03#analysis

I devised a DFS based backtracking solution, the problem is I donot know how to keep track of visited states in an efficient manner. The way I am doing is right now, I am starting from a random state and I am doing a DFS traversal and each time I push a node on to the stack I make sure it is not something we have already encountered on the path, by keeping track of a linked list! So for every update onto the I am doing a linked list traversal all the way to the root.

I am able to solve test case 1, but cannot solve test case 2. Please suggest if it is possible to do the backtracking more efficiently. Thank you!

#include <bits/stdc++.h>
typedef long long ll;

using namespace std;
struct Node {
	Node* par;
	pair<int, int> vl;
	int cnt;
};
void tracePtr(Node* nd) {
	vector<pair<int, int>> v;
	
	while(nd) {
		v.push_back(nd->vl);
		nd = nd->par;
	}
	cout<<"POSSIBLE"<<endl;
	for (int i=v.size()-1; i >= 0; --i) {
		cout<<v[i].first+1 << " "<<v[i].second+1<<endl;
	}
	
}
int main() {
	int t;
	cin >> t;
	for (int tt = 1; tt <= t; ++tt) {
		int nr, nc;
		cin >> nr >> nc;
		bool fnd=false;
		cout << "Case #"<<tt<<": ";
		for (int r=0; r< nr && !fnd; ++r) {
			for(int c=0; c < nc && !fnd; ++c) {
				stack<Node*> st;
				Node* nd = new Node;
				nd->par=nullptr;
				nd->vl.first=r;
				nd->vl.second=c;
				nd->cnt=1;
				st.push(nd);
				while(!st.empty()) {

					auto cur=st.top();
					st.pop();
     			//	cout << cur->cnt<< st.size() <<endl;

					if (cur->cnt == nr*nc) {
						fnd=true;
						tracePtr(cur);
						break;
					}
					for (int rr=0;rr < nr;++rr) {
						if (rr == cur->vl.first) {
							continue;
						}
						for (int cc=0; cc < nc; ++cc) {
							if (cc == cur->vl.second) {
								continue;
							}
							if (((rr+cc) != (cur->vl.first+cur->vl.second)) && 
							((rr-cc) != (cur->vl.first - cur->vl.second))) {
							//	cout << "Here"<<endl;
								
								bool valid =true;
								auto curr = cur;
								while(curr) {
									if ((curr->vl.first == rr) && (curr->vl.second == cc)) {
										valid =false;
									}
									curr = curr->par;
								}
								if (valid) {
									Node* nd = new Node;
									nd->par=cur;
									nd->vl.first=rr;
									nd->vl.second=cc;
									nd->cnt=cur->cnt+1;
									st.push(nd);
								}
								
							}
						}
					}
				}
			}
		}
		if (!fnd) {
			cout << "IMPOSSIBLE"<<endl;
		}
	}
	// your code goes here
	return 0;
}
Теги codejam, #dfs, #backtracking

История

 
 
 
 
Правки
 
 
  Rev. Язык Кто Когда Δ Комментарий
en2 Английский codex666 2021-03-22 19:47:21 282
en1 Английский codex666 2021-03-22 19:42:34 2806 Initial revision (published)