I have implemented the following algorithms for a competitive programming problem. But for the First method, it gives a TLE (Time Limit Exceeded).
In contrast, the second implementation was accepted as the correct answer even though its time complexity is higher than the first one since it uses the .erase method inside a loop.
May I know the reason why the second implementation was faster than the first
Please refer to the first if statement inside the while(true) loop
First Implementation (TLE)
bool isEmpty (vector<int> a) {
sort(a.begin(), a.end());
return a.size() == 0 || a[a.size() - 1] == 0;
}
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int m, n, l;
cin>>n>>l;
vector<int> k;
vector<int> q;
for (int i=0; i<n; i++){
int ki;
cin>>ki;
k.push_back(ki);
}
cin>>m;
for (int i=0; i<m; i++){
int qi;
cin>>qi;
q.push_back(qi);
}
vector<int> bagsNeeded;
for (int qi:q){
if (qi % l == 0){
bagsNeeded.push_back(qi / l);
}
else {
bagsNeeded.push_back((qi / l) + 1);
}
}
sort(bagsNeeded.begin(), bagsNeeded.end());
int i = 0;
int c = 0;
while(true){
auto itr = lower_bound(bagsNeeded.begin(), bagsNeeded.end(), k[i]);
// Difference between the two implementations is inside this if statement
if (itr == bagsNeeded.end()){
if (isEmpty(bagsNeeded)) break;
else {
int bags = k[i];
int carriable = 0;
int j = bagsNeeded.size() - 1;
c++;
while(bags > 0 && j >= 0){
if (bagsNeeded[j] <= bags){
bags -= bagsNeeded[j];
bagsNeeded[j] = 0;
}
else {
bagsNeeded[j] -= bags;
bags = 0;
}
j--;
}
}
}
else if (itr == bagsNeeded.begin()){
bagsNeeded[0] -= k[i];
if (bagsNeeded[0] == 0){
bagsNeeded.erase(itr);
}
c++;
}
else {
bagsNeeded[itr - bagsNeeded.begin()] -= k[i];
if (bagsNeeded[itr - bagsNeeded.begin()] == 0){
bagsNeeded.erase(itr);
}
c++;
}
i++;
if (i == n){
i = 0;
}
}
cout<<c<<"\n";
return 0;
}
Second Implementation (Accepted)
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int m, n, l;
cin>>n>>l;
vector<int> k;
vector<int> q;
for (int i=0; i<n; i++){
int ki;
cin>>ki;
k.push_back(ki);
}
cin>>m;
for (int i=0; i<m; i++){
int qi;
cin>>qi;
q.push_back(qi);
}
vector<int> bagsNeeded;
for (int qi:q){
if (qi % l == 0){
bagsNeeded.push_back(qi / l);
}
else {
bagsNeeded.push_back((qi / l) + 1);
}
}
sort(bagsNeeded.begin(), bagsNeeded.end());
int i = 0;
int c = 0;
while(true){
auto itr = lower_bound(bagsNeeded.begin(), bagsNeeded.end(), k[i]);
if (itr == bagsNeeded.end()){
if (bagsNeeded.size() == 0) break;
else {
int bags = k[i];
int carriable = 0;
int j = bagsNeeded.size() - 1;
c++;
while(bags > 0 && j >= 0){
if (bagsNeeded[j] <= bags){
bags -= bagsNeeded[j];
bagsNeeded.erase(bagsNeeded.begin() + j);
}
else {
bagsNeeded[j] -= bags;
bags = 0;
}
j--;
}
}
}
else if (itr == bagsNeeded.begin()){
bagsNeeded[0] -= k[i];
if (bagsNeeded[0] == 0){
bagsNeeded.erase(itr);
}
c++;
}
else {
bagsNeeded[itr - bagsNeeded.begin()] -= k[i];
if (bagsNeeded[itr - bagsNeeded.begin()] == 0){
bagsNeeded.erase(itr);
}
c++;
}
i++;
if (i == n){
i = 0;
}
}
cout<<c<<"\n";
return 0;
}
Related
I am getting segmentation error , it gives output when only print ans[k] inside the function then it
gives corrct output but in main when I try to print ans[k] then it gives segmentation
i am new at progamming so i don't know more about it so please help me it's my assigment
question is
I have to create a array of factors of a number upto 4 * 10^6
Core Dump/Segmentation fault is a specific kind of error caused by accessing memory that “does not belong to you.”
When a piece of code tries to do read and write operation in a read only location in memory or freed block of memory, it is known as core dump.
It is an error indicating memory corruption.
#include <bits/stdc++.h>
using namespace std;
#define int long long int
vector<int> arr(1000001,0);
vector<int> ans;
bool isPrime(int n)
{
if (n <= 1)
return false;
if (n <= 3)
return true;
if (n % 2 == 0 || n % 3 == 0)
return false;
for (int i = 5; i * i <= n; i = i + 6)
if (n % i == 0 || n % (i + 2) == 0)
return false;
return true;
}
void factorpush()
{
for (int k = 5; k <= 4000001; k += 4)
{
if (isPrime(k))
{
arr[k] = 1;
}
}
arr.clear();
ans.clear();
for (int k = 5; k <= 4000001; k += 4)
{
if (arr[k] == 1)
{
int n = (k / 4);
ans[n] = (2 * n) - 1 + k;
}
else
{
vector<int> v;
for (int i = 1; i*i < k; i++)
{
if (k % i == 0)
{
if (k / i == i && i != k)
v.push_back(i);
else
{
if (i != k)
{
v.push_back(i);
}
if (k / i != k)
{
v.push_back(k/ i);
}
}
}
}
int count = k;
int count2 = 0;
for (auto x : v)
{
if (x != 1 && x!=k)
{
int n = (k/4);
count2 += ((2*n - 1)/x);
count += ((2*n - 1)/x)*x;
}
}
int n1 = (k/4);
int val = (2*n1) - 1 - count2;
count += val;
ans[n1] = count;
//cout<<ans[n1]<<"\n";
}
}
}
int32_t main()
{
factorpush();
int n;
cin>>n;
cout<<ans[n]<<"\n";`
return 0;
}
I didn't read your code well and there may be other errors, but at least the combination of
vector<int> arr(1000001,0);
and
for (int k = 5; k <= 4000001; k += 4)
{
if (isPrime(k))
{
arr[k] = 1;
}
}
is bad because arr[k] will go further than allocated.
You have to allocate enough elements like
vector<int> arr(4000002,0);
Also accessing arr[k] and ans[n] after arr.clear(); and ans.clear(); and without adding any elements is bad because the clear() function erases all elements from the vector. Also checking for arr[k] == 1 after the erasure doesn't make sense. Not understanding your code well, it looks like
arr.clear();
ans.clear();
should be replaced with something like
ans.clear();
ans.resize(1000001);
In one of the largest cities in Bytland, Bytesburg, construction of the second stage of the metro is underway. During the construction of the first stage, N stations were built that were not interconnected. According to the master plan, the metro in Bytesburg should consist of no more than two lines. each metro line is straight. The president of the company responsible for laying the lines wants to make sure that no more than two metro lines can be laid, so that all stations built lie on at least one of the two
Exaple 1
input:
6
0 1
1 1
2 1
0 2
1 3
2 2
output:
no
Example 2
input:
6
2 2
4 6
1 0
2 1
6 1
1 1
output:
yes
I wrote the code, but on the seventh test on the testing system, it gives the wrong answer. Help me please. This is my code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct line {
int k, b;
bool x = false;
long long c = 0;
};
int n;
vector<line> lines;
vector<pair<int, int>> p;
bool Is3PointsOnLine(pair<float, float> p1, pair<float, float> p2, pair<float, float> p3) {
return ((p3.first - p1.first)*(p2.second - p1.second) == (p3.second - p1.second)*(p2.first - p1.first));
}
bool PointIsOnLine(line l, int x, int y) {
if (!l.x) {
if (y == ((l.k * x) + l.b))
return true;
}
else {
if (x == l.b)
return true;
}
return false;
}
line f(pair<int, int> c1, pair<int, int> c2) {
int x1 = c1.first;
int y1 = c1.second;
int x2 = c2.first;
int y2 = c2.second;
line ans;
if (x2 != x1) {
ans.k = (y2 - y1) / (x2 - x1);//fix
ans.b = -(x1 * y2 - x1 * y1 - x2 * y1 + x1 * y1) / (x2 - x1);
ans.x = false;
ans.c = 0;
}
else {
ans.k = 0;
ans.b = x1;
ans.x = true;
ans.c = 0;
}
return ans;
}
int a() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (j != i) {
for (int k = 0; k < n; k++) {
if ((k != i) && (k != j) && (Is3PointsOnLine(p[i], p[j], p[k]))) {
lines.push_back(f(p[i], p[j]));
return 0;
}
}
}
}
}
}
int main() {
cin >> n;
p.resize(n);
vector<int> not_used;
for (int i = 0; i < n; i++)
cin >> p[i].first >> p[i].second;
if (n < 5) {
cout << "yes";
return 0;
}
else {
a();
if (lines.size() == 0) {
cout << "no";
return 0;
}
pair<int, int> e = { -8,-8 };
for (int i = 0; i < n; i++) {
if (PointIsOnLine(lines[0], p[i].first, p[i].second)) {
lines[0].c++;
}
else if (e.first == -8) {
e.first = i;
}
else if (e.second == -8) {
e.second = i;
lines.push_back(f(p[e.first], p[e.second]));
for (int j = 0; j <= i; j++) {
if (PointIsOnLine(lines[1], p[j].first, p[j].second)) {
lines[1].c++;
}
}
e = { -5,-5 };
}
else if (PointIsOnLine(lines[1], p[i].first, p[i].second)) {
lines[1].c++;
}
else {
cout << "no";
return 0;
}
}
if (lines[0].c+1 >= n && e.first != -2 && e.second == -8) {
cout << "yes";
return 0;
}
else if (lines[0].c + lines[1].c >= n) {
cout << "yes";
return 0;
}
else {
cout << "no";
return 0;
}
}
return 0;
}
Code v2
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct line {
pair<int, int> p1, p2;
long long c = 0;
};
int n;
vector<line> lines;
vector<pair<int, int>> p;
bool Is3PointsOnLine(pair<float, float> p1, pair<float, float> p2, pair<float, float> p3) {
return ((p3.first - p1.first)*(p2.second - p1.second) == (p3.second - p1.second)*(p2.first - p1.first));
}
//лежит ли точка на прямой
bool PointIsOnLine(line l, int x, int y) {
return Is3PointsOnLine(l.p1, l.p2, {x , y});
}
int a() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (j != i) {
for (int k = 0; k < n; k++) {
if ((k != i) && (k != j) && (Is3PointsOnLine(p[i], p[j], p[k]))) {
line sdafsadf;
sdafsadf.p1 = p[i]; sdafsadf.p2 = p[j];
lines.push_back(sdafsadf);
return 0;
}
}
}
}
}
}
int main() {
cin >> n;
p.resize(n);
vector<int> not_used;
for (int i = 0; i < n; i++)
cin >> p[i].first >> p[i].second;
if (n < 5) {
cout << "yes";
return 0;
}
else {
//ищем первую прямую
a();
if (lines.size() == 0) {
cout << "no";
return 0;
}
pair<int, int> e = { -8,-8 };
for (int i = 0; i < n; i++) {
if (PointIsOnLine(lines[0], p[i].first, p[i].second)) {
lines[0].c++;
}
else if (e.first == -8) {
e.first = i;
}
else if (e.second == -8) {
e.second = i;
line sdafsadf;
sdafsadf.p1 = p[e.first]; sdafsadf.p2 = p[e.second];
lines.push_back(sdafsadf);
for (int j = 0; j <= i; j++) {
if (PointIsOnLine(lines[1], p[j].first, p[j].second)) {
lines[1].c++;
}
}
e = { -5,-5 };
}
else if (PointIsOnLine(lines[1], p[i].first, p[i].second)) {
lines[1].c++;
}
else {
cout << "no";
return 0;
}
}
if (lines[0].c+1 >= n && e.first != -2 && e.second == -8) {
cout << "yes";
return 0;
}
else if ((lines[0].c + lines[1].c >= n) && (lines[0].p1 != lines[1].p1) && (lines[0].p1 != lines[1].p2) && (lines[0].p2 != lines[1].p1) && (lines[0].p2 != lines[1].p2)) {
cout << "yes";
return 0;
}
else {
cout << "no";
return 0;
}
}
return 0;
}
Your function f is horribly broken because it uses integer division. Then everything after that which relies on k and b, including PointIsOnLine, will give wrong results. Is3PointsOnLine seems ok, change your line struct to store two points, not slope+intercept, and then PointInOnLine can just call Is3PointsOnLine.
I'm amazed that you passed any non-trivial test cases with such a bug.
This also will not work
if (lines[0].c + lines[1].c >= n)
because you aren't testing that lines[1] isn't a duplicate of lines[0].
Also, you can reach lines[0].c + lines[1].c == n and still miss one station completely, if another station lies at the intersection of the lines and gets double-counted.
I am currently a high school student and a beginner at programming on C++ and LUA.
I am trying to make a program using CodeBlocks, and I just made this code on C++:
#include <cstring>
using namespace std;
int st[20],n,ok,x,p;
char v[8] = "abcdefg",voc[] = "aeiouAEIOU",lit[] = "a";
// (n - 1)! n=9
void afisare(int k){
int i;
for (i=1;i<=k;i++)
cout<<v[st[i]]<<" ";
cout<<endl;
}
void valid(int k,int&ok){
int i;
ok = 0;
//cout<<v[st[k]];
if (strchr(lit,v[st[1]]) != NULL && strchr(lit,v[st[k]]) != NULL)
ok = 1;
for (i = 1; i <= k-1; i++)
if (st[k] == st[i])
ok = 0;
}
void back(){
int k;
k = 1;
x = 0;
st[k] = -1;
while(k > 0){
ok = 0;
while (ok==0 && st[k]<n - 1){
st[k] = st[k] + 1;
valid(k,ok);
}
if (ok == 1)
if (k == n){ //
afisare(k);
x++;
}
else {
k++;
st[k] = -1;}
else
k--;
}
}
int main()
{
//cin>>p;
n = strlen(v);
//while (p > n)
//cin>>p;
back();
cout<<endl<<"x! = "<<x;
return 0;
}
However it only shows:
x! = 0
Does anyone know the solution for this program? I am currently beginner at backtracking by the way.
#include<iostream>
#include<random>
#include<ctime>
#include<cstdlib>
#include<vector>
#include<algorithm>
using namespace std;
int path_checker(vector<pair<int,int> > path, int i, int j)
{
//cout<<"path_checker"<<endl;
std::vector<pair<int, int> >::iterator it;
for(it = path.begin(); it!=path.end();it++)
if(it->first == i && it->second ==j)
return 1;
return 0;
}
int isVertex(int i, int j, int n)
{
//cout<<"isVertex"<<endl;
if((i>=0) && (j>=0))
{
if((i <= n) && (j <= n))
return 1;
}
return 0;
}
void printAllPathsU(int *array, int i, int j, int n, vector<pair<int,int> > path,int index)
{
// cout<<"PrintAllPathsU_first"<<endl;
// vector<pair<int,int>> path2 = {0};
if((i == n) && (j == n))
{
if((path_checker(path,i,j)))
{
cout<<"Inside printing path"<<endl;
//vector<pair<int,int> >::iterator it;
for(int i = 0; i < path.size();i++)
cout<<"a["<<path[i].first<<"]["<<path[i].second<<"] ";
return;
}
else
{
path.push_back(make_pair(i,j));
cout<<"Inside printing path"<<endl;
//vector<pair<int,int> >::iterator it;
for(int i = 0; i < path.size();i++)
cout<<"a["<<path[i].first<<"]["<<path[i].second<<"] ";
return;
}
}
if((*((array+i*n)+j) == 1) && (!path_checker(path,i,j)))
{
//cout<<path.size()<<endl;
path.push_back(make_pair(i,j));
index++;
//len++;
if(isVertex(i,j-1,n))
printAllPathsU((int *)array,i,j-1,n,path,index);
if(isVertex(i-1,j,n))
printAllPathsU((int *)array,i-1,j,n,path,index);
if(isVertex(i,j+1,n))
printAllPathsU((int *)array,i,j+1,n,path,index);
if(isVertex(i+1,j,n))
printAllPathsU((int *)array,i+1,j,n,path,index);
}
else if((*((array+i*n)+j) == 1) && (path_checker(path,i,j)))
{
//cout<<"inside second else"<<endl;
return;
}
else if(*((array+i*n)+j) == 0)
{
// cout<<"inside third else"<<endl;
return;
}
}
void printAllPaths(int *array, int n)
{
vector<pair<int,int> > path;
//cout<<"PrintALLPaths"<<endl;
printAllPathsU(array, 0, 0, n, path, 0);
}
int main()
{ //populating matrix
int n;
cout << "Enter value of n (for n x n matrix): ";
cin >> n;
int i;
int j;
int k;
int test=1;
int array[n][n];
int randomval;
int total_elements = n*n;
int counter_0 = 0;
int max_0 = 0.2 * total_elements;
cout << "Number of zeros(20% of n*n) in matrix: ";
cout<<max_0<<endl;
int count=0;
srand(time(0));
for(i = 0;i < n;i++)
{
for(j = 0;j<n;j++)
{
array[i][j]=-1;
}
}
while(count < total_elements)
{
i=rand()%n;
j=rand()%n;
if(array[i][j]==1 || array[i][j]==0)
{
continue;
}
else if(array[i][j] == -1)
{
count+=1;
if(i==0 && j==0)
{
array[i][j]=1;
}
else if (counter_0 < max_0)
{
counter_0+=1;
array[i][j] = 0;
}
else if(counter_0 >= max_0)
{
test+=1;
array[i][j] = 1;
}
}
else{continue;}
}
cout<<"# of 1s:"<<test<<" & # of 0s:"<<counter_0<<endl;
cout<<"Elements Populated:"<<count<<endl;
cout<<"Total Elements in matrix:"<<total_elements<<endl;
if(counter_0 < max_0)
{ cout<<"adding more zeros"<<endl;
while(k < (max_0 - counter_0))
{
i = rand()%n;
j = rand()%n;
if(array[i][j] == 0)
{
}
else
{
array[i][j] = 0;
k+=1;
}
}
}
for(i = 0;i < n;i++)
{
for(j = 0;j<n;j++)
{
cout<<array[i][j]<<" ";
}
cout<<endl;
}
//printing paths
if(array[1][0]==0 && array[0][1]==0)
{
cout<<"No Possible paths homie #snorlaxiseverywhere";
}else
{
//printing paths
printAllPaths((int *)array, n);
}
return 0;
}
The question is to traverse through a n * n matrix populated with 1s and 0s, with the number of 0s in the matrix being 20% of the total number of elements, and print all paths and then the shortest path from the [0][0] to [n][n], using four direction: up,down,left and right.
So far I have tried to implement printing all possible paths. However, I am stuck in an infinite loop in the
else if((*((array+i*n)+j) == 1) && (!path_checker(path,i,j)))
{
...
}
I cout the path.size() to check what the size is becoming in each instance, and the output is somewhat like :
35
48
37
...and so on infinitely (values ranging approx between 30-50)
Any ideas how to correct this?
EDIT : Changed up some logic, not stuck infinite loop. But all of the function calls exit through the "second else" and the "third else" inside the function - printAllPathsU(...).
Thanks!
As long as the question is how to "print all paths", you should have an infinite loop because there are infinitely many paths. If the question is how to print all non-self-intersecting paths, then this rephrasing gives a hint on how to go about solving the problem.
I've been working on a program in one of my college classes. I have been having trouble with the implementation of my LRU code as it is not displaying any errors or anything, but compiles. There are two parts. The main that we input the values into, which we then specify which algorithm we want to use to find page faults. I know the main works, along with the FIFO algorithm, but I'm not getting anything with my LRU code (It compiles and "runs" but displays nothing as if I did not click to use the algorithm). Can anyone help me figure out what is wrong?
main.cpp
#include <iostream>
#include <string>
//#include "fifo.cpp"
#include "lru.cpp"
//#include "optimal.cpp"
using namespace std;
int main() {
// List of different variables
string pagestring;
int fs,pn[50], n;
// Prompt for page references
cout<<"Virtual Memory Simulation\nBy blah\n----------\nEnter the number of pages : " << endl;
cin >> n;
cout<<"\n-------------\nPlease enter a list of page numbers separated by commas.\n"<< endl;
cin>>pagestring;
// algorithm to use
char algo;
while (true) {
// Prompt algorithm to use
cout<<"----------\nPlease select an algorithm to use.\n\n1: First-In-First-Out (FIFO)\n2: Least-Recently-Used (LRU)\n3: Optimal\n0: Quit\n"<<endl;
cin>>algo;
if (algo == '1') {
//fifo(pagestring);
}
else if (algo == '2'){
LRU_Execute(pagestring, n);
}
else if (algo == '3'){
cout<<"Optimal Not yet coded"<<endl;
}
else if (algo == '0'){
break;
}
else {
cout<<"Invalid choice. Please try again."<<endl;
}
}
cout<<"Goodbye!!"<<endl;
};
LRU.cpp
#include <iostream>
#include <string>
using namespace std;
class pra
{
int fs,z;
int frame[50], frame1[50][2], pn[50], n, cnt, p, x;
public:
pra();
void init(string pagestring);
void getdata(string pagestring, int n);
void lru(int* pn, int n, string pagestring);
};
pra::pra()
{
int i;
for (i = 0; i < fs; i++)
{
frame[i] = -1;
}
for (i = 0; i < fs; i++)
{
frame1[i][0] = -1;
frame1[i][1] = 0;
}
p = 0;
cnt = 0;
}
void pra::init(string pagestring)
{
int i;
for (i = 0; i < fs; i++)
{
frame[i] = -1;
}
for (i = 0; i < fs; i++)
{
frame1[i][0] = -1;
frame1[i][1] = 0;
}
p = 0;
cnt = 0;
}
void pra::getdata(string pagestring, int n)
{
fs=3;
// index to loop through input string
int i = 0;
// current input string character
char z = pagestring[i];
int x = 0;
//cout << "\nEnter the page numbers : ";
while (z != '\0'){
// skip over commas and spaces
if (!(z == ',')) {
pn[x] = z;
x++;
// cout<<pn[x]<<"-This is pn[x]\n";
}
z = pagestring[++i];
}
//cout<<pn[x]<<"-This is pn[x] AGAIN\n";
this->lru(pn, n, pagestring);
}
void pra::lru(int* pn, int n, string pagestring)
{
init(pagestring);
int ind = 0, fault = 0, pi = 0, j, fn;
char i, z;
p = 0;
cnt = 0;
int min;
cout<<n<<"---"<<i<<" - "<<j<<" - "<<" - "<<fn<<" - "<<z;
for (i = 0; i < fs; i++)
{
frame1[i][0] = -1;
frame1[i][1] = 0;
}
pi = 0;
for (i = 0; i < n; i++)
{
j = 0;
if (ind > fs - 1)
ind = 0;
fault = 1;
min = 999;
while (j < fs)
{
if (frame1[j][0] = pn[pi])
{
fault = 0;
p++;
frame1[j][1] = p;
goto l2;
}
if (frame1[j][1] < min)
{
min = frame1[j][1];
fn = j;
}
j++;
}
j = 0;
while (j < fs)
{
if (frame1[j][0] = -1)
{
fault = 1;
fn = j;
goto l2;
}
j++;
}
ind++;
l2:
if (fault == 1)
{
p++;
frame1[fn][0] = pn[pi];
frame1[fn][1] = p;
cnt++;
}
cout << "\nElement: " << pn[pi];
pi++;
for (z = 0; z < fs; z++)
{
cout << "\t" << frame1[z][0];
}
if (fault == 1)
cout << "\t**Page Fault**";
else
cout << "\t--No Page Fault--";
}
cout << "\nTotal number of page faults: " << cnt;
cout << "\n";
}
void LRU_Execute(string pagestring, int n)
{
pra p;
int j, fault = 0, i, pi, z, fn, ind = 0, ans, ch;
p.getdata(pagestring, n);
//p.lru();
while (ans == 1);
//return 1;
}