Can I say that this algorithm can solve the n-queens problem? - algorithm

#include<iostream>
#include<algorithm>
#define INT unsigned __int128
using namespace std;
INT base[25][25],lit[25],n,error=0;
void expbase(INT p,INT q)
{
for(INT i=1;i<=n;i++)
{
base[p][i]=1;
base[i][q]=1;
}
INT cp=p,cq=q;
while(cp>=1&&cp<=n&&cq>=1&&cq<=n)
{
base[cp][cq]=1;
cp--;
cq++;
}
cp=p,cq=q;
while(cp>=1&&cp<=n&&cq>=1&&cq<=n)
{
base[cp][cq]=1;
cp++;
cq--;
}
cp=p,cq=q;
while(cp>=1&&cp<=n&&cq>=1&&cq<=n)
{
base[cp][cq]=1;
cp--;
cq--;
}
cp=p,cq=q;
while(cp>=1&&cp<=n&&cq>=1&&cq<=n)
{
base[cp][cq]=1;
cp++;
cq++;
}
base[p][q]=2;
return;
}
void make(INT ed)
{
INT d[25][25]={0,},ch=0,mult=1;
for(INT i=1;i<=n;i++)
{
INT cop[25][25]={0,},co=0;
if(lit[i])continue;
for(INT p=1;p<=n;p++)
{
for(INT q=1;q<=n;q++)
{
cop[p][q]=d[p][q];
d[p][q]=0;
}
}
if(i==ed)
{
/*Insert Queen*/
for(INT j=1;j<=n;j++)
{
if(cop[i][j]!=(1<<mult)-1&&!base[i][j]){expbase(i,j);return;}
else if(j==n){error=1;return;}
}
}
else
{
/*Check the possibility*/
for(INT j=1;j<=n;j++)
{
if(!base[i][j])
{
INT ch[25][25]={0,};
for(INT p=1;p<=n;p++)
for(INT q=1;q<=n;q++)
d[p][q]=(d[p][q]<<mult);
for(INT p=1;p<=n;p++)if(!ch[i][p]){d[i][p]+=(1<<mult)-1;ch[i][p]=1;}
for(INT p=1;p<=n;p++)if(!ch[p][j]){d[p][j]+=(1<<mult)-1;ch[p][j]=1;}
INT ci=i,cj=j;
while(ci>=1&&ci<=n&&cj>=1&&cj<=n)
{
if(!ch[ci][cj]){d[ci][cj]+=(1<<mult)-1;ch[ci][cj]=1;}
ci--;cj++;
}
ci=i,cj=j;
while(ci>=1&&ci<=n&&cj>=1&&cj<=n)
{
if(!ch[ci][cj]){d[ci][cj]+=(1<<mult)-1;ch[ci][cj]=1;}
ci++;cj++;
}
ci=i,cj=j;
while(ci>=1&&ci<=n&&cj>=1&&cj<=n)
{
if(!ch[ci][cj]){d[ci][cj]+=(1<<mult)-1;ch[ci][cj]=1;}
ci++;cj--;
}
ci=i,cj=j;
while(ci>=1&&ci<=n&&cj>=1&&cj<=n)
{
if(!ch[ci][cj]){d[ci][cj]+=(1<<mult)-1;ch[ci][cj]=1;}
ci--;cj--;
}
for(INT p=1;p<=n;p++)
for(INT q=1;q<=n;q++)
if(!ch[p][q])d[p][q]+=(cop[p][q]|cop[i][j]);
co++;
}
}
mult*=co;
}
}
return;
}
int main()
{
scanf("%lld",&n);
for(INT i=1;i<=n;i++)
{
for(INT j=1;j<=n;j++)
{
scanf("%lld",&base[i][j]);
if(base[i][j]==2)lit[i]=1;
}
}
cout<<endl;
for(INT i=n;i>=1;i--)
{
if(!lit[i])make(i);
if(error){cout<<"does not exist"<<endl;return 0;}
}
for(INT i=1;i<=n;i++)
for(INT j=1;j<=n;j++)
if(base[i][j]==0)base[i][j]=2;
cout<<endl;
for(INT i=1;i<=n;i++)
{
for(INT j=1;j<=n;j++)
printf("%llx ", (unsigned long long)(base[i][j] & 0xFFFFFFFFFFFFFFFF));
cout<<endl;
}
return 0;
}
The above code is written to solve the n-queens problem, which is the problem presented to solve the P versus NP problem.
Currently, the above code only works if the multiplication of the number of zeros present in each column is 128 or less.
I wonder if I can solve the n-queens problem by making several modifications to this algorithm.

Related

why this heap sort code fails for some input array

can any body please tell me whats wrong in this code? i have already spent almost 1 day behind this to find out whats wrong in this. this heap sort code fails for some input.
i.e. for input array arr = {1,5,2,4,3,6,0,7,9,8}.
this code should print
{9,8,7,6,5,4,3,2,1,0} but this code gives {5,9,8,7,6,4,3,2,1,0}
#include<iostream>
using namespace std;
void printarr(int *arr,int n)
{
for(int i=0;i<=n;i++)
cout<<arr[i]<<" ";
cout<<endl;
}
void heapify(int *arr,int i,int n)
{
int max=i;
if(arr[max]<arr[(2*i)+1] && (2*i)+1<=n)
max=(2*i)+1;
if(arr[max]<arr[(2*i)+2] && (2*i)+2<=n)
max=(2*i)+2;
if(i!=max)
{
swap(arr[max],arr[i]);
heapify(arr,max,n);
}
}
void buildheap(int *arr,int i,int j)
{
for(;i<=(i+j)/2;i++)
heapify(arr,i,j);
}
int* heapsort(int *arr,int i,int n)
{
buildheap(arr,0,n-1);
int *b,index=0;
b=new int[n];
while(n>=i)
{
b[index++]=arr[i];
arr[i]=arr[n--];
heapify(arr,i,n);
}
return b;
}
int main()
{
int *arr,n;
cout<<"how many elements?"<<endl;
cin>>n;
cout<<"enter elements : "<<endl;
arr=new int [n];
for(int i=0;i<n;i++)
cin>>arr[i];
arr=heapsort(arr,0,n-1);
printarr(arr,n-1);
}
I found 2 errors
You should first check out of bound condition and then compare.
Change if(arr[max]<arr[(2*i)+1] && (2*i)+1<=n) max=(2*i)+1;
To if((2*i)+1<=n && arr[max]<arr[(2*i)+1])
If you are building a heap, You run loop like this. Because of what you have written in heapify
Change void buildheap(int *arr,int i,int j) { for(;i<=(i+j)/2;i++) heapify(arr,i,j); }
To void buildheap(int *arr,int i,int j) { for(i = j/2; i >= 0;i--) heapify(arr,i,j);}
Final Code
#include<iostream>
using namespace std;
void printarr(int *arr,int n)
{
for(int i=0;i<=n;i++)
cout<<arr[i]<<" ";
cout<<endl;
}
void heapify(int *arr,int i,int n)
{
int max=i;
max=(2*i)+1;
if((2*i)+2<=n && arr[max]<arr[(2*i)+2])
max=(2*i)+2;
if(i!=max)
{
swap(arr[max],arr[i]);
heapify(arr,max,n);
}
}
void buildheap(int *arr,int i,int j)
{
for(i = j/2; i >= 0;i--)
heapify(arr,i,j);
}
int* heapsort(int *arr,int i,int n)
{
buildheap(arr,0,n-1);
int *b,index=0;
b=new int[n];
while(n>=i)
{
b[index++]=arr[i];
arr[i]=arr[n--];
heapify(arr,i,n);
}
return b;
}
int main()
{
int *arr,n;
cout<<"how many elements?"<<endl;
cin>>n;
cout<<"enter elements : "<<endl;
arr=new int [n];
for(int i=0;i<n;i++)
cin>>arr[i];
arr=heapsort(arr,0,n-1);
printarr(arr,n-1);
}

distance between any two nodes in a graph(based on edges between them)

The below code in c++ is to find the distance between any two nodes in a graph but there is some logical error where I tried to find but can't. Everything seems to be perfect but I can say that there is something wrong with a break inside if condition inside for loop which is inside while(s.!empty()).
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
int find_distance(int link[100][100],int start,int dest,int n,int e)
{
start=start-1;
dest=dest-1;
if(start==dest)return 0;
int visited[100];
int distance;
for(int i=0;i<n;i++)
{
visited[i]=0;
}
stack<int>s;
int k;s.push(start);
visited[start]=1;
bool found=false;
int count =0;
while(!s.empty())
{
k=s.top();
int i;
int check_point=1;
for(i=0;i<n;i++)
{
if(link[k][i]==1 && visited[i]!=1)
{
s.push(i);
count ++;
check_point=0;
if(i==dest)
{
cout<<"found";
found=true;
}
break;
}
}
if(check_point==1)
{
s.pop();
count--;
}
if(found)break;
}
return count;
}
int main()
{
int n,e,a,b;
int link[100][100];
cout<<"enter the number of vertices and edges";
// cin>>n>>e;
n=5;e=4;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(i==j)
link[i][j]=0;
else
link[i][j]=INT_MAX;
cout<<link[i][j]<<" ";
}
cout<<endl;
}
int input[4][2]={{1,2},{1,3},{2,4},{2,5}};
for(int i=0;i<e;i++)
{
a=input[i][0];
b=input[i][1];
link[a-1][b-1]=1;
link[b-1][a-1]=1;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cout<<link[i][j]<<" ";
}
cout<<endl;
}
while(true) {
cout<<endl<<"enter the starting point .. ";
int start;
cin>>start;
int dest;
cout<<endl<<"enter the destination point .. ";
cin>>dest;
int distance = find_distance(link,start,dest,n,e);
cout<<endl<<"distance is "<<distance;
}
return 0;
}

Wrong answer on LIS

I am solving a problem on my college judge where i have to all lis sequences. The n is very small so, i am generating all subsets and if they are increasing and of longest length, i am printing it. What's wrong in my code? Or may be any problem with order?
#include<iostream>
#include<cmath>
#include<algorithm>
#include<sstream>
#include<vector>
#include<map>
using namespace std;
int a[100005];
int l[100005];
vector< vector<int> > V;
int main()
{
int n,r,c;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
l[i]=1;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<i;j++)
{
if(a[i]>a[j]&&l[i]<l[j]+1)
{
l[i]=l[j]+1;
}
}
}
vector<int> v;
r=0;
int cnt=0;
for(int i=0;i<pow(2,n);i++)
{
for(int j=0;j<n;j++)
{
if(i & (1<<j))
{
v.push_back(a[j]);
}
}
int f=0;
if(v.size()==*max_element(l,l+n))
{
int ss=v.size();
for(int x=0;x<ss-1;x++)
{
if(v[x]>=v[x+1])
{
f=-1;
break;
}
}
if(f==0)
{
V.push_back(v);
}
}
v.clear();
}
for(int i=0;i<V.size();i++)
{
for(int j=0;j<V[i].size();j++)
{
cout<<V[i][j];
if(j!=V[i].size()-1)
cout<<" ";
}
cout<<endl;
}
return 0;
}

Memory Limit Exceeded with Segment Tree in SPOJ Posters?

Given a horizontal section of wall , and N layers of paints applied from co-ordinates Xi to Yi , Output the distinct number of layers visible.
Here is the problem link http://www.spoj.com/problems/POSTERS/
Here is my solution http://ideone.com/gBJKnL
Approach :
I tried solving the problem by lazily updating child node values through a Segment Tree , the most recent value replaces the older one in their lazy updates. This way only the recent paint gets applied into the horizontal cross-section. although the code works fine on custom test cases , It takes a lot of memory and gets aborted by the Online Judge .
#include <iostream>
#include <set>
#include <vector>
#define MAX 10000000+100
typedef long long int ll;
using namespace std;
ll Tree[3*MAX],lazy[MAX*2];
void Update(ll s,ll start,ll end,ll left,ll right,ll value)
{
if(lazy[s]!=0)
{
Tree[s]=(lazy[s]*(end-start+1));
if(start!=end)lazy[2*s+1]=lazy[s],lazy[s*2+2]=lazy[s];
lazy[s]=0;
}
if(start>end||left>end||right<start)return;
if(start>=left&&end<=right)
{
Tree[s] = (value*(end-start+1));
if(start!=end)
{
lazy[2*s+1]=value;
lazy[2*s+2]=value;
}
return ;
}
ll mid=(start+end)/2;
Update(2*s+1,start,mid,left,right,value);
Update(2*s+2,mid+1,end,left,right,value);
Tree[s] = Tree[s*2+1]+Tree[2*s+2];
}
ll Read(ll s,ll start,ll end,ll left,ll right)
{
if(start>end||start>right||end<left)return 0;
if(lazy[s]!=0)
{
Tree[s]=(lazy[s]*(end-start+1));
if(start!=end)
{
lazy[2*s+1]=lazy[s];
lazy[2*s+2]=lazy[s];
}
lazy[s]=0;
}
if(start>=left&&end<=right)return Tree[s];
else return (Read(2*s+1,start,(start+end)/2,left,right)+Read(2*s+2,1+((start+end)/2),end,left,right));
}
int main() {
// your code goes here
ll t;
cin>>t;
while(t--)
{
ll n,z=1,li=-1;
cin>>n;
vector<pair<ll,ll> > b;
for(ll i=0;i<n;i++)
{
ll u,v;
li = max(li,v);
cin>>u>>v;
b.push_back(make_pair(u-1,v-1));
}
for(auto v: b)
Update(0,0,li+2,v.first,v.second,z++);
set<ll> a;
for(ll i=0;i<li+2;i++)cout<<Read(0,0,li+2,i,i)<<" ",a.insert(Read(0,0,li+2,i,i));
cout<<endl;
cout<<a.size()-1<<endl;
}
return 0;
}
Here is how you should be doing it:
#include <bits/stdc++.h>
#define mx 400005
using namespace std;
int tr[mx], lz[mx];
int t, n, l, r;
void update(int node, int s, int e, int l, int r, int val)
{
if(lz[node]!=0)
{
tr[node]=lz[node];
if(s!=e)
{
lz[node*2]=lz[node];
lz[node*2+1]=lz[node];
}
lz[node]=0;
}
if(s>e || r<s || l>e)
return;
if(s>=l && e<=r)
{
tr[node]=val;
if(s!=e)
{
lz[2*node]=val;
lz[2*node+1]=val;
}
return;
}
int m=s+(e-s)/2;
update(2*node,s,m,l,r,val);
update(2*node+1,m+1,e,l,r,val);
tr[node]=val;
//tr[node]=max(tr[2*node],tr[2*node+1]);
}
int query(int node, int s, int e, int l, int r)
{
if(r<s || e<l)
return 0;
if(lz[node]!=0)
{
tr[node]=lz[node];
if(s!=e)
{
lz[node*2]=lz[node];
lz[node*2+1]=lz[node];
}
lz[node]=0;
}
if(l<=s && r>=e)
return tr[node];
int m=s+(e-s)/2;
return query(2*node,s,m,l,r)+query(2*node+1,m+1,e,l,r);
}
int main()
{
//cout << "Hello world!" << endl;
cin>>t;
while(t--)
{
for(int i=0; i<mx; i++) tr[i]=0;
cin>>n;
int lr[n+1][2];
map<int,bool> mark;
vector<int> vec;
//int c=0;
for(int i=0; i<n; i++)
{
cin>>l>>r;
lr[i][0]=l;
lr[i][1]=r;
if(mark[l]==0)
{
vec.push_back(l);
mark[l]=1;
}
if(mark[r]==0)
{
vec.push_back(r);
mark[r]=1;
}
}
sort(vec.begin(), vec.end());
map<int,int> mp;
int c=1;
for(int i=0; i<vec.size(); i++)
mp[vec[i]]=c++;
for(int i=0; i<n; i++)
{
//cout<<mp[lr[i][0]]<<" "<<mp[lr[i][1]]<<"\n";
update(1,1,vec.size(),mp[lr[i][0]],mp[lr[i][1]],i+1);
}
set<int> ans;
for(int i=1; i<=vec.size(); i++)
{
//cout<<query(1,1,vec.size(),i,i)<<" ";
ans.insert(query(1,1,vec.size(),i,i));
}
int k = ans.size();
if(ans.find(0) != ans.end())
k--;
printf("%d\n",k);
}
return 0;
}

2D vector subscript out of range

It says vector subscript out of range when achieving if statement. I think I added extra int to floor, or extra floor vector to 2D vector. I am using VS 2010(C++)
I tried to find it on other questions but not succeeded.
bool is_perfect_square(int);
int main()
{
int cust;
vector<int>floor;
vector<vector<int>>hotel;
floor.push_back(0);
hotel.push_back(floor);
hotel[0][0]=1;
for(cust=2; ; cust++)
{
for(int i=0; i<=hotel.size(); i++)
{
if(is_perfect_square(cust+hotel[i][floor.size()]))
{
floor.push_back(0);
hotel[i][cust]=cust;
break;
}
else
{
hotel.push_back(floor);
hotel[hotel.size()][0]=cust;
}
}
}
int sum=0;
for(int a=1; a<=hotel.size(); a++)
{
for(int b=1; b<=floor.size(); b++)
{
if(pow(a-1,2)+pow(b-1,2)==14234886498625)
sum+=hotel[a-1][b-1];
}
}
cout<<sum<<endl;
system("pause");
return 0;
}
bool is_perfect_square(int n)
{
int root=floor(sqrt(n));
return n == root * root;
}
I put my answers in the comments.
bool is_perfect_square(int);
int main()
{
int cust;
vector<int>floor;
vector<vector<int>>hotel;
floor.push_back(0);
hotel.push_back(floor);
hotel[0][0]=1;
// you may not be able to get out of this loop
// because the "break" below only exits one level of the loop.
for(cust=2; ; cust++)
{
// this should be changed to "i<hotel.size()",
// because the subscript of a vector ranges from 0 to its size minus one.
for(int i=0; i<=hotel.size(); i++)
{
// here "floor.size()" should be floor.size() - 1, the same reason.
if(is_perfect_square(cust+hotel[i][floor.size()]))
{
floor.push_back(0);
hotel[i][cust]=cust;
break;
}
else
{
hotel.push_back(floor);
hotel[hotel.size()][0]=cust;
}
}
}
int sum=0;
for(int a=1; a<=hotel.size(); a++)
{
for(int b=1; b<=floor.size(); b++)
{
if(pow(a-1,2)+pow(b-1,2)==14234886498625)
sum+=hotel[a-1][b-1];
}
}
cout<<sum<<endl;
system("pause");
return 0;
}
bool is_perfect_square(int n)
{
int root=floor(sqrt(n));
return n == root * root;
}

Resources