hostel visit question (priority queue application ) - c++

question: Dean of MAIT is going to visit Hostels of MAIT. As you know that he is a very busy person so he decided to visit only the first "K" nearest Hostels. Hostels are situated on a 2D plane. You are given the coordinates of hostels and you have to answer the Rocket distance of Kth nearest hostel from the origin ( Dean's place )
Input Format
The first line of input contains Q Total no. of queries and K There are two types of queries:
first type: 1 x y For query of 1st type, you came to know about the coordinates ( x, y ) of the newly constructed hostel. second type: 2 For query of 2nd type, you have to output the Rocket distance of Kth nearest hostel till now.
//The Dean will always stay at his place ( origin ). It is guaranteed that there will be at least k queries of type 1 before the first query of type 2.
Rocket distance between two points ( x2 , y2 ) and ( x1 , y1 ) is defined as (x2 - x1)2 + (y2 - y1)2
Constraints
1 < = k < = Q < = 10^5 -10^6 < = x , y < = 10^6
Output Format
For each query of type 2 output the Rocket distance of Kth nearest hostel from Origin.//
This is my code:
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
class roomno
{
public:
int x;
int y;
roomno(int x,int y)
{
this->x=x;
this->y=y;
}
void print()
{
cout<<"location"<<"("<<x<<","<<y<<")"<<endl;
}
int distance ()
{
return (x*x+y*y);
}
};
class roomcompare
{
public:
bool operator() (roomno r1,roomno r2)
{
return r1.distance()>r2.distance();
}
};
int main()
{
int x[1000]},y[1000];
int l,k=0;
priority_queue<roomno,vector<roomno>,roomcompare> pq;
int n,i,j;
cin>>n>>l;
//cin>>n;
cin.ignore();
for( i=0;i<n;i++)
{
cin>>x[i];
}
cin.ignore();
for( j=0;j<n;j++)
{
cin>>y[j];
}
cin.ignore();
for(i=0;i<n;i++ )
{
roomno r1(x[i],y[i]);
pq.push(r1);
}
while(!pq.empty()&&k!=l)
{ k++;
roomno r2=pq.top();
r2.print();
pq.pop();
}
return 0;
}
Original link to code: https://codeshare.io/2j1bkA
What's wrong with my code?

Please consider adding what problem you are facing in your post. I've seen your code but I couldn't help with your code as I even saw a syntax error in your code and didn't know if it was the problem.
If I didn't misunderstand your question, std::set will fit better than priority queue as it is not possible to remove the largest item in a priority queue(min heap). The following code should work:
#include <iostream>
#include <set>
using namespace std;
using ll = long long;
multiset<ll> distances;
int main() {
ll n, k;
cin >> n >> k;
for(ll i = 0; i < n; ++i) {
ll query;
cin >> query;
if (query == 1) {
ll x, y;
cin >> x >> y;
distances.insert(x * x + y * y);
if (distances.size() > k) {
distances.erase(--distances.end());
}
} else {
cout << *distances.rbegin() << '\n';
}
}
return 0;
}

Related

Check if the system of equations have a solution

Question:
There are N variables x1, x2, x3, ...... xN.
There are M triplets such that triple {i,j,c} indicate that xi = xj + c and so each triplet denote an equation. Check if the system of equations have atleast one solution.
My idea:
I considered the system of equations as a graph of N nodes labelled from 1 to N. If {i,j,c} is a triplet then, i->j is an edge with weight c and j->i is an edge with weight -c. With 0 as the source, I applied Bellman Ford algorithm to detect any negative cycles. If there is any positive sum cycle, then there must also be a negative sum cycle, which can be traced with Bellman Ford.
Following is the code
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
#define INF (1<<30)
int main(){
int T;
cin>>T;
while(T--){
int N;int M;
cin>>N;cin>>M;
vector<vector<int>> edges;
for (int i=0;i<M;++i){
int first;int second;int third;
cin>>first;cin>>second;cin>>third;
first--;second--;
edges.push_back({first,second,third});
edges.push_back({second,first,-third});
}
vector<int> distances(N,INF);
distances[0] = 0;
for (int i=1;i<=N;++i){
for (int j=0;j<edges.size();++j){
int from = edges[j][0];
int to = edges[j][1];
int weight = edges[j][2];
if (distances[from]+weight<distances[to]){
distances[to] = distances[from] + weight;
}
}
}
int flag = 0;
for (int j=0;j<edges.size();++j){
int from = edges[j][0];
int to = edges[j][1];
int weight = edges[j][2];
if (distances[from]+weight<distances[to]){
flag = 1;
break;
}
}
if (flag==1){
cout << "NO" << endl;
}
else{
cout << "YES" << endl;
}
}
}
Is the idea correct? I am unable to generate test cases against the above logic. But, the code failed to give correct output for many test cases.
Can somebody point out the mistake.
Thank you

Solving Wormholes (ZCO 2012)

Description:
The year is 2102 and today is the day of ZCO. This year there are N contests and the starting and ending times of each contest is known to you. You have to participate in exactly one of these contests. Different contests may overlap. The duration of different contests might be different.
There is only one examination centre. There is a wormhole V that transports you from your house to the examination centre and another wormhole W that transports you from the examination centre back to your house. Obviously, transportation through a wormhole does not take any time; it is instantaneous. But the wormholes can be used at only certain fixed times, and these are known to you.
So, you use a V wormhole to reach the exam centre, possibly wait for some time before the next contest begins, take part in the contest, possibly wait for some more time and then use a W wormhole to return back home. If you leave through a V wormhole at time t1 and come back through a W wormhole at time t2, then the total time you have spent is (t2 - t1 + 1). Your aim is to spend as little time as possible overall while ensuring that you take part in one of the contests.
You can reach the centre exactly at the starting time of the contest, if possible. And you can leave the examination centre the very second the contest ends, if possible. You can assume that you will always be able to attend at least one contest–that is, there will always be a contest such that there is a V wormhole before it and a W wormhole after it.
For instance, suppose there are 3 contests with (start,end) times (15,21), (5,10), and (7,25), respectively. Suppose the V wormhole is available at times 4, 14, 25, 2 and the W wormhole is available at times 13 and 21. In this case, you can leave by the V wormhole at time 14, take part in the contest from time 15 to 21, and then use the W wormhole at time 21 to get back home. Therefore the time you have spent is (21 - 14 + 1) = 8. You can check that you cannot do better than this.
Input:
The first line contains 3 space separated integers N, X, and Y, where N is the number of contests, X is the number of time instances when wormhole V can be used and Y is the number of time instances when wormhole W can be used. The next N lines describe each contest. Each of these N lines contains two space separated integers S and E, where S is the starting time of the particular contest and E is the ending time of that contest, with S < E. The next line contains X space separated integers which are the time instances when the wormhole V can be used. The next line contains Y space separated integers which are the time instances when the wormhole W can be used.
Output:
Print a single line that contains a single integer, the minimum time needed to be spent to take part in a contest.
My code:
#include <iostream>
#include <algorithm>
#include <vector>
#include <bits/stdc++.h>
#define loop(i,n) for(int i=0;i<n;++i)
#define FOR(i,a,b) for (int i = a; i < b; ++i)
#define ll long long
#define inf 9223372036854775807
#define printgrid(arr,m,n){cout<<"[";for(int i=0;i<m;++i){if(i!=0)cout<<" ";cout<<"[";for(int j=0;j<n;++j){cout<<arr[i][j];if(j!=n-1)cout<<" ";}cout<<"]";if(i!=m-1)cout<<endl;}cout<<"]"<<endl;}
using namespace std;
int searchl(int *arr,int s,int v)
{
int l=0;
int r=s-1;
while(l<=r)
{
int m = (l+r)/2;
if (arr[m] == v) return v;
if(arr[m]<v)
{
l = m + 1;
} else {
r = m - 1;
}
}
if (r<0) r=0;
return arr[r];
}
int searchh(int *arr,int s,int v)
{
int l=0;
int r=s-1;
while(l<=r)
{
int m = (l+r)/2;
if (arr[m] == v) return v;
if(arr[m]<v)
{
l = m + 1;
} else {
r = m - 1;
}
}
if(l>s-1) l=s-1;
return arr[l];
}
int main() {
int n,x,y;
cin>>n>>x>>y;
vector<pair<int,int>> v(n);
int a[x];
int b[y];
loop(i,n) cin >> v[i].first >> v[i].second;
loop(i,x) cin >> a[i];
loop(i,y) cin >> b[i];
sort(a,a+x);
sort(b,b+y);
int mn = 0x7fffffff;
int l;
int u;
loop(i,n)
{
l = searchl(a,x,v[i].first);
u = searchh(b,y,v[i].second);
mn = min(mn,(u-l+1));
}
cout << mn << endl;
}
What I tried is I use binary search for the lower range and upper range. and return the closest integer in the list. This should result in the lowest difference. This code AC's in 90% of the testcases however fails two testcases with a wrong answer.
Correct code:
#include <iostream>
#include <algorithm>
#include <vector>
#include <bits/stdc++.h>
#define loop(i,n) for(int i=0;i<n;++i)
#define FOR(i,a,b) for (int i = a; i < b; ++i)
#define ll long long
#define inf 9223372036854775807
#define printgrid(arr,m,n){cout<<"[";for(int i=0;i<m;++i){if(i!=0)cout<<" ";cout<<"[";for(int j=0;j<n;++j){cout<<arr[i][j];if(j!=n-1)cout<<" ";}cout<<"]";if(i!=m-1)cout<<endl;}cout<<"]"<<endl;}
using namespace std;
int searchl(int *arr,int s,int v)
{
int l=0;
int r=s-1;
while(l<=r)
{
int m = (l+r)/2;
if (arr[m] == v) return v;
if(arr[m]<v)
{
l = m + 1;
} else {
r = m - 1;
}
}
if (r<0) return -1;
return arr[r];
}
int searchh(int *arr,int s,int v)
{
int l=0;
int r=s-1;
while(l<=r)
{
int m = (l+r)/2;
if (arr[m] == v) return v;
if(arr[m]<v)
{
l = m + 1;
} else {
r = m - 1;
}
}
if(l>s-1) return -1;
return arr[l];
}
int main() {
cin.sync_with_stdio(false);
cin.tie(NULL);
int n,x,y;
cin>>n>>x>>y;
vector<pair<int,int>> v(n);
int a[x];
int b[y];
loop(i,n) cin >> v[i].first >> v[i].second;
loop(i,x) cin >> a[i];
loop(i,y) cin >> b[i];
sort(a,a+x);
sort(b,b+y);
int mn = 0x7fffffff;
int l;
int u;
loop(i,n)
{
l = searchl(a,x,v[i].first);
u = searchh(b,y,v[i].second);
if(u==-1 or l==-1) continue;
mn = min(mn,(u-l+1));
}
cout << mn << endl;
}

Perfect squares in a given range: abnormal execution of loops

Program number 1:
In a given range a and b where a<=b, I want to find whether a number is a perfect quare, if yes then print its root. Therefore, I wrote the following code:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
float squaredroot(int n) {
float low = 0.0, mid;
float high = (float)n+1;
while ((high-low) > 0.00001) {
mid = (low+high) / 2;
if (mid*mid < n) {
low = mid;
}
else {
high = mid;
}
}
return low;
}
int main() {
int a,b,i=0; cin>>a>>b;
float roo=0.0;
for(i=a;i<=b;i++){
roo=squaredroot(i);
if(floor(roo)==roo){
cout<<roo<<endl;
}
}
return 0;
}
For the given input 1 5 the output should be 2. But, the above program is not printing any value.
Nevertheless, when I tried running another program using the same base concept as Program number 1, that's mentioned above, It was executed perfectly.
The task for the following program is to check whether the input is a perfect square or not. If yes, then print the root of the number, else print "Not a perfect square!". Here is the code for the Program number 2:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
float squaredroot(int n) {
float low = 0.0, mid;
float high = (float)n+1;
while ((high-low) > 0.00001) {
mid = (low+high) / 2;
if (mid*mid < n) {
low = mid;
}
else {
high = mid;
}
}
return low;
}
int main() {
int a; cin>>a;
float roo=0.0;
roo=squaredroot(a);
if(floor(roo)==roo){
cout<<roo<<endl;
}
else{
cout<<"Not a perfect square!"<<endl;
}
return 0;
}
I am unable to find the mistake in the first program. Please help.
Instead of messing about with the square root function, consider this:
Consecutive squares are separated by succeeding odd numbers.
It's pretty darned fast to add some integers. Also you are skipping more and more numbers each time.
Square root takes you to floats. This keeps the problem in integers, where it belongs.
So, to solve your problem elegantly, just do this:
#include <iostream>
using std::cout;
void print_perfect_square( int start, int end ) {
int x = 0, nthOdd = 1;
while ( x <= end ) {
if ( x >= start ) {
cout << x << " is a square and its root is "
<< nthOdd - 1 << '\n';
}
x += 2*nthOdd - 1;
++nthOdd;
}
}
int main() {
// it should find 9 and 16
print_perfect_square(6,17);
cout << '\n';
// it sholuld skip negatives
print_perfect_square(-10,5);
cout << '\n';
// it should print 25,36...
print_perfect_square(20,100);
return 0;
}
As Gyro Gearloose said, the problem is that squaredroot(4) returns 1.99999809, so floor(roo)!=roo. One way to fix this is to change the condition (floor(roo)==roo) to (fabs(roo - floor(roo+0.5)) < 0.00001). Notice that I'm using the same 0.00001 from the function squaredroot.

Isolating some vertices in a weighted tree with minimum cost

Suppose we are given a weighted tree and some set of vertices of that tree. The problem is to isolate those vertices(e.g. there should not be paths between them) by removing edges from the tree, such that the sum of the weights of removed edges is minimal.
I have been trying to solve this problem for about two hours, then I found solution in C++, but there was no explanation. As I understood it uses Dynamic Programming technique.
My question is what is the basic idea of solving this problem?
Thanks!
Here is the solution.
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
#define PB push_back
#define MP make_pair
typedef long long LL;
const int MAXN = 100005;
const LL inf = 1LL << 55;
int N, K;
bool bad[MAXN];
LL dp[MAXN][2];
vector<pair<int, int> > adj[MAXN];
void dfs(int u, int fa) {
dp[u][1] = 0;
dp[u][0] = bad[u] ? inf : 0;
for (int i = 0; i < adj[u].size(); i++) {
int v = adj[u][i].first, w = adj[u][i].second;
if (v != fa) {
dfs(v, u);
dp[u][1] += min(dp[v][0], dp[v][1] + w);
dp[u][1] = min(dp[u][1], dp[u][0] + dp[v][1]);
if (!bad[u])
dp[u][0] += min(dp[v][0], dp[v][1] + w);
}
}
}
int main() {
cin >> N >> K;
for (int i = 1; i < N; i++) {
int a, b, c;
cin >> a >> b >> c;
adj[a].PB(MP(b, c)); adj[b].PB(MP(a, c));
}
memset(bad, false, sizeof(bad));
for (int i = 0; i < K; i++) {
int x;
cin >> x;
bad[x] = true;
}
dfs(0, -1);
LL ret = min(dp[0][0], dp[0][1]);
cout << ret << endl;
return 0;
}
Formally, the problem is, given an acyclic undirected graph with weighted edges, together with a set of terminal vertices, find the minimum set of edges whose removal means that, for all pairs of distinct terminals, those terminals are no longer connected.
Root the graph arbitrarily and treat it as a general tree. We run a dynamic program that operates bottom-up on the vertices. Each vertex u has two labels: dp[u][0] is the minimum weight of edges to be removed in the subtree rooted at u so that no terminal in the subtree is connected to another terminal or to u, and dp[u][1] is the minimum removal weight that leaves exactly one subtree terminal connected to u. We have a recurrence
{ infinity if v is a terminal
dp[u][0] = { sum dp[v][0] otherwise
{ children v of u
dp[u][1] = min dp[v][1] + sum min(dp[w][0], dp[w][1] + weight(uw)),
children v of u other children w of v
taking an empty min to be infinity.

Wrong logic in approximating e^1 :( [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I've written code using class object to calculate the value of e^1 by approximation using the summation of series given below, but seems like i can't get the logic to work properly.I tried running it to 5 terms for approximation but my answer was 1.2 only where it should be around 2.7038...
e^1 is given by the series 1 + 1/1! + 1/2! + 1/3! ...
#include <iostream>
#include <stdlib.h>
using namespace std;
class factorial
{
public:
double loopfactorial ( double y)
{
double value;
for (int a=0; a<=y; a++)
{
value=1;
value = value*a;
}
return value;
}
};
int main()
{
factorial calcu;
int x;
double sum;
cout<<"Enter the number of terms to approximate exponent:"<<endl;
cin>>x;
for (int y=1; y<=x-1; y++)
{
int n = calcu.loopfactorial(y);
sum=1.0;
sum = sum + 1/n;
}
cout<<"The value of e is "<<sum<<endl;
return 0;
}
For reference and the benefit of future readers, here's the "correct" code:
#include <iostream>
#include <cstdlib>
int main()
{
unsigned int terms;
if (!(std::cout << "Number of terms: " && std::cin >> terms))
{
std::cout << "Error, I did not understand you.\n";
return EXIT_FAILURE;
}
double e = terms > 0 ? 1.0 : 0.0, term = 1.0;
for (unsigned int n = 1; n < terms; ++n)
{
term /= n;
e += term; // this is "e += 1/n!"
}
std::cout << "e is approximately " << e << "\n";
}
(The code can be trivially extended to compute ex for any x.)
You should move the variable initializations out of the loops - you're resetting them over and over.
Side note: it's rather pointless to put loopfactorial in a class.
I found three problems with your code, both are similar to each other
1. in loopfactorial(), value=1 should be defined before the loop body
2. in main(), sum=1.0 should be defined before the loop body
3. in loopfactorial(), loop variable a should have been initialized with either 1 or 2 instead of 0.
Try moving your initial values outside the loop:
#include <iostream>
#include <stdlib.h>
using namespace std;
class factorial
{
public:
double loopfactorial ( double y)
{
double value;
// MOVED INITIAL VALUE HERE
value=1;
for (int a=1; a<=y; a++)
{
value = value*a;
}
return value;
}
};
int main()
{
factorial calcu;
int x;
double sum;
cout<<"Enter the number of terms to approximate exponent:"<<endl;
cin>>x;
// MOVED INITIAL VALUE HERE
sum=1.0;
for (int y=1; y<=x-1; y++)
{
int n = calcu.loopfactorial(y);
sum = sum + 1/n;
}
cout<<"The value of e is "<<sum<<endl;
return 0;
}