Given two arrays, first has 'n' numbers and the second one has 'n-m' numbers; the second array is not in the same order as the first. If there are several numbers with the same value, they end up in the order of the positions in the original array. Also, all the values from the second array are also found in the first array. I have to find the 'm' missing numbers in the order in which they appear in the first array.
input:
7 3
12 34 45 29 100 87 32
100 87 12 34
output:
45 29 32
#include <iostream>
using namespace std;
int main()
{
int n, missing_number = 0, m, i, j, v[1201], w[1201];
cin >> n >> m;
for (i = 0; i < n; ++i) {
cin >> v[i];
}
for (i = 0; i < n - m; ++i) {
cin >> w[i];
}
for (i = 0; i < n; ++i) {
missing_number = 1;
for (j = 0; j < n - m; ++j) {
if (v[i] == w[j]) {
missing_number = -1;
}
}
if (missing_number == 1) {
cout << v[i] << " ";
}
}
if (m == 0)
cout << "there are no missing numbers";
return 0;
}
my code doesn't work for repeating numbers like:
7 3
2 6 1 9 3 2 4
4 1 2 3
where my output should be:
6 9 2
Your program seems to be outputting the correct result. However, I felt that I need to refactor your code to improve its readability and remove the bad practices used in it.
The below is the same as your code with a bit of improvement:
#include <iostream>
#include <array>
#include <limits>
int main( )
{
std::array<int, 1201> arr1; // use std::array instead of raw arrays
std::array<int, 1201> arr2;
std::size_t arr1_size { }; // renamed n
std::size_t arr2_size { }; // renamed m
std::cin >> arr1_size >> arr2_size;
if ( arr2_size == 0 ) // this if statement should be here to help end
{ // the program early on to prevent the execution
// of the for-loops
std::cout << "There are no missing numbers.\n";
return 0;
}
for ( std::size_t idx { }; idx < arr1_size; ++idx ) // use std::size_t
{ // for the loop counters
std::cin >> arr1[ idx ];
}
for ( std::size_t idx { }; idx < arr1_size - arr2_size; ++idx )
{
std::cin >> arr2[ idx ];
}
for ( std::size_t arr1_idx { }; arr1_idx < arr1_size; ++arr1_idx )
{
bool isNumberMissing { true }; // this should be of type bool
for ( std::size_t arr2_idx { }; arr2_idx < arr1_size - arr2_size; ++arr2_idx )
{
if ( arr1[ arr1_idx ] == arr2[ arr2_idx ] )
{
isNumberMissing = false;
// this is my trick for solving your code's bug
arr2[ arr2_idx ] = std::numeric_limits<int>::min( );
break; // break here to improve performance
}
}
if ( isNumberMissing )
{
std::cout << arr1[ arr1_idx ] << " ";
}
}
std::cout << '\n';
}
Sample input/output #1:
7 3
12 34 45 29 100 87 32
100 87 12 34
45 29 32
Sample input/output #2:
7 3
2 6 1 9 3 2 4
4 1 2 3
6 9 2
Note: See Why is "using namespace std;" considered bad practice?
Related
For example, I have a code that generates all sequences of zeros and ones of length 4. Can I do it using his example?
#define n 2
int x[n];
int main() {
int i, k;
for (i = 0; i < n; i++) {
x[i] = 0;
}
while (1) {
for (i = 0; i < n; i++) {
cout << x[i];
}
cout << endl << endl;
for (k = n - 1; k >= 0 && x[k] == 1; k--) {
x[k] = 0;
}
if (k == -1) {
break;
} else {
x[k] = 1;
}
}
return 0;
}
Example:
Basically your task is to output all N-digit numbers in base K in ascending order.
I encoded two solutions for your task. First solution looks very similar to your code. It is non-recursive, but algorithmical.
Base of this solution is following algorithm - we go from tail of a number while all digits are equal to K - 1 (for example equal to 9 in case of famous base 10) and zeroize them, and first digit smaller than K - 1 we increment. This way we generate next number using previous number. This is also how usually people increment any long number by 1 in their minds.
Try it online!
#include <functional>
#include <vector>
#include <iostream>
void Gen(size_t n, size_t k, auto const & outf) {
std::vector<size_t> a(n);
while (true) {
outf(a);
int i = 0;
for (i = a.size() - 1; i >= 0; --i) {
if (a[i] < k - 1)
break;
a[i] = 0;
}
if (i < 0)
break;
++a[i];
}
}
int main() {
Gen(2, 3, [](auto const & v){
for (auto e: v)
std::cout << e << " ";
std::cout << std::endl;
});
}
Output:
0 0
0 1
0 2
1 0
1 1
1 2
2 0
2 1
2 2
Second solution uses approach of Recursive Function.
For those who knows recursive functions this second solution looks simpler and doesn't need invention of any algorithms like in first solution.
Basically in a loop I increment most significant digit (left-most) and recursively with same loop I iterate through all possible numbers in a tail. When tail goes through all possible numbers only then most significant digit is incremented again.
Try it online!
#include <functional>
#include <vector>
#include <iostream>
void Gen(size_t n, size_t k, auto const & outf) {
std::vector<size_t> a(n);
std::function<void(size_t pos)> Rec = [&](auto pos){
if (pos >= n) {
outf(a);
return;
}
for (size_t i = 0; i < k; ++i) {
a[pos] = i;
Rec(pos + 1);
}
};
Rec(0);
}
int main() {
Gen(2, 3, [](auto const & v){
for (auto e: v)
std::cout << e << " ";
std::cout << std::endl;
});
}
Output:
0 0
0 1
0 2
1 0
1 1
1 2
2 0
2 1
2 2
If the task is to improve your code with minimal changes, to achieve final goal, then it will be following snippet (see n and K defined at start of program).
Try it online!
#include <iostream>
using namespace std;
#define n 2
#define K 3
int x[n];
int main() {
int i, k;
for (i = 0; i < n; i++) {
x[i] = 0;
}
while (1) {
for (i = 0; i < n; i++) {
cout << x[i] << " ";
}
cout << endl;
for (k = n - 1; k >= 0 && x[k] == K - 1; k--) {
x[k] = 0;
}
if (k == -1) {
break;
} else {
++x[k];
}
}
return 0;
}
Output:
0 0
0 1
0 2
1 0
1 1
1 2
2 0
2 1
2 2
Suppose I have a vector<vector<vector<int> > > result.
The only size I know before hand is the inner and outer vector, which are of size k.
if I print result I get this (for k = 3):
i = 0
0 1 2
3 4 5
i = 1
6 7 8
9 10 11
12 13 14
i = 2
15 16 17
18 19 20
What I need to do is to print every combinations of k rows from each of vector of vectors of i's. In other words, what I need is the following output:
0 1 2
6 7 8
15 16 17
0 1 2
6 7 8
18 19 20
0 1 2
9 10 11
15 16 17
...
3 4 5
12 13 14
18 19 20
Hope I was clear about the desired output. I have tried a thousand of different loops, trying to save in another vector<vector<int> > but no success so far. I really am lost and any help would be greatly appreaciated.
The code to generate the above output is here:
(I'm sorry, I know it is an ugly code but it was the closest I could get to demonstrate my problem in a MCVE code)
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<vector<vector<int> > > result;
int k = 3;
vector<vector<int> > randomVectors;
//I'll create seven random vectors
//In my original problem, I don't have this number beforehand
int number = 0;
for(int i = 0; i < 7; i++){
vector<int> temp;
for(int j = 0; j < k; j++){
temp.push_back(number);
number++;
}
randomVectors.push_back(temp);
}
//Vector of vector to assign to "result"
vector<vector<int> > randomVectors_0;
randomVectors_0.push_back(randomVectors[0]);
randomVectors_0.push_back(randomVectors[1]);
vector<vector<int> > randomVectors_1;
randomVectors_1.push_back(randomVectors[2]);
randomVectors_1.push_back(randomVectors[3]);
randomVectors_1.push_back(randomVectors[4]);
vector<vector<int> > randomVectors_2;
randomVectors_2.push_back(randomVectors[5]);
randomVectors_2.push_back(randomVectors[6]);
result.push_back(randomVectors_0);
result.push_back(randomVectors_1);
result.push_back(randomVectors_2);
cout << "Printing the 3D vector" << endl;
for(int i = 0; i < k; i++){
cout << "i = " << i << endl << endl;
for(int j = 0; j < result[i].size(); j++){
for(int m = 0; m < k; m++){
cout << result[i][j][m] << " ";
}
cout << endl;
}
cout << endl;
}
return 0;
}
Compiler version: gcc (tdm-1) 4.7.1
I would make a rows_to_print vector that starts with all 0's. Then once a loop, it'll increment the last value by 1. If that value is greater than the size of the last vector, then reset it to 0 and increment the next value up the list, etc... you're done looping when every value in rows_to_print is greater than the size of each of the vectors:
void print_rows(std::vector<size_t> rows, std::vector<std::vector<std::vector<int>>> v) {
for(size_t x = 0; x < v.size(); x++) {
for(size_t y = 0; y < v.at(x).at(rows.at(x)).size(); y++) {
std::cout << v.at(x).at(rows.at(x)).at(y) << ' ';
}
std::cout << std::endl;
}
}
bool increment_rows(std::vector<size_t> &rows, std::vector<std::vector<std::vector<int>>> v) {
if(!rows.size()) return false; //empty rows, BAD
rows.at(rows.size() - 1)++;
for(int x = rows.size() - 1; x >= 0; x--) {
if(rows.at(x) >= v.at(x).size()) {
if(x <= 0) { return false; } //first row is done, then we're done!
rows.at(x-1)++; //increment previous row and set us back to 0 (overflow)
rows.at(x) %= v.at(x).size();
}
}
return true;
}
int main() {
...
std::vector<size_t> rows_to_print(k, 0);
print_rows(rows_to_print, result);
while(increment_rows(rows_to_print, result)) {
print_rows(rows_to_print, result);
}
}
See it in action here: ideone
how to print 1-10 after that if i input one of them the number will be disappear.
ex:
Output: 1 2 3 4 5 6 7 8 9 10
Input:1
Output:2 3 4 5 6 7 8 9 10
Input:5
Output:2 3 4 6 7 8 9 10
(only using while or do-while or for)->(not using array)
//let's say that the variable x contains the inputted number, 5 in this case
for (int i = 1; i <= 10; i++){
if (i != x)
printf("%d ", i);
}
The output will be:
1 2 3 4 6 7 8 9 10
#include <bitset>
#include <iostream>
...
constexpr int N = 10;
std::bitset<N+1> mask {-1ul};
while (true) {
int inp;
cin >> inp;
if (inp < 1 || inp > N)
continue;
mask.reset(inp);
for (int i = 1; i < N; ++i) {
if (mask.test(i)) {
std::cout << i << '\n';
}
}
}
I have tested this code on VS2017. I believe you will get an idea of how to do it. Of course, you can improve the efficiency of the source code.
#include "stdafx.h"
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
constexpr int iBitNum = 10;
std::bitset<iBitNum + 1> mask;
mask.set();
int _size = mask.count();
for (int i = 0; i < _size; ++i)
{
mask[i] = 0;
}
int inp = 0;
int b = 0;
while (true)
{
cout << "Enter the number which you do not want to display" << endl;
cin >> inp;
cout << "Here is the result" << endl;
for (size_t i = 0; i < iBitNum; i++)
{
if (i+1==inp)
{
continue;
}
b = mask[i] | i+1;
cout << b << " ";
}
cout << endl;
}
return 0;
}
I was trying to solve this problem with the following code. But the answers aren't accurate for all inputs.
Problem Statement
Ikbal has two arrays a and b of length N, initially all values equals to zero. We have Q operation. Let's define three types of operations on this arrays:
1 l r c Increase al,al+1,...,ar by c.
2 l r c Increase bl,bl+1,...,br by c.
3 l r Print (al∗bl)+(al+1∗bl+1)+...+(ar∗br) in modulo 1000000007
Input Format
First line of the input consists of N and Q. Next Q lines contain one of the three types of operations.
Constraints
1≤N≤109
1≤Q≤200000
1≤c≤10000
1≤l≤r≤N
Output Format
Whenever you get a type 3 operation, you should print the answer in a new line.
Sample Input
5 3
1 1 5 5
2 2 4 2
3 3 4
Sample Output
20
Explanation
After first operation arrays look like this:
a=5,5,5,5,5
b=0,0,0,0,0
After second operation arrays look like this:
a=5,5,5,5,5
b=0,2,2,2,0
Answer of the third operation: 5∗2+5∗2=20
**MY code **
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
vector<int> a,b,c;
int n,q,r,p;
cin >> n;
cin >> q;
for(int i=0;i<q;i++) {
cin >> r;
a.push_back(r);
if(r==3) {
p = 3;
} else {
p = 4;
}
for(int j=1;j<p;j++) {
cin >> r;
a.push_back(r);
}
}
vector<int> aa(n,0),bb(n,0);
int g,start,endd,val,anss=0;
for(int i=0;i<a.size();) {
if(a[i]==3) {
start = a[i+1]-1;
endd = a[i+2]-1;
if(start==endd) {
anss = (aa[start]*bb[start])%1000000007;
} else {
anss = (aa[start]*bb[start] + aa[endd]*bb[endd])%1000000007;
}
cout << anss << endl;
i+= 3;
} else {
start = a[i+1] - 1;
endd = a[i+2];
val = a[i+3];
if(a[i]==1) {
for(int j=start;j<endd;j++) {
aa[j] += val;
}
} else {
for(int j=start;j<endd;j++) {
bb[j] += val;
}
}
i+= 4;
}
}
/*
for(int i=0;i<n;i++) {
cout << aa[i] << " " ;
cout << bb[i] << endl;
}
for(int i=0;i<a.size();i++) {
cout << a[i] << endl;
} */
return 0;
}
Expected output for given input :
http://i.stack.imgur.com/4OsSo.jpg
It's not an overflow problem. This:
if(start==endd)
anss = (aa[start]*bb[start])%1000000007;
else
anss = (aa[start]*bb[start] + aa[endd]*bb[endd])%1000000007;
is flat wrong. You misread the instructions.
Be careful not to cause overflow.
You have to calculate (al∗bl)+(al+1∗bl+1)+...+(ar∗br), not (al∗bl)+(ar∗br)
At least, the output for the given input
10 20
1 9 9 6768
2 5 5 2202
3 7 7
2 3 9 1167
2 1 7 8465
3 1 5
2 1 1 1860
3 9 9
2 5 5 2153
1 5 7 749
3 1 1
2 8 10 3129
3 1 1
1 2 10 2712
2 1 8 79
1 1 6 4645
1 7 7 1358
3 2 10
1 9 9 8677
3 8 10
is corrected.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int add(int a, int b) {
int r = a + b;
if (r >= 1000000007) r -= 1000000007;
return r;
}
int mul(int a, int b) {
int r = 0;
while (b > 0) {
if (b % 2 != 0) r = add(r, a);
a = add(a, a);
b /= 2;
}
return r;
}
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
vector<int> a,b,c;
int n,q,r,p;
cin >> n;
cin >> q;
for(int i=0;i<q;i++) {
cin >> r;
a.push_back(r);
if(r==3) {
p = 3;
} else {
p = 4;
}
for(int j=1;j<p;j++) {
cin >> r;
a.push_back(r);
}
}
vector<int> aa(n,0),bb(n,0);
int g,start,endd,val,anss=0;
for(int i=0;i<a.size();) {
if(a[i]==3) {
start = a[i+1]-1;
endd = a[i+2]-1;
#if 0
if(start==endd) {
anss = (aa[start]*bb[start])%1000000007;
} else {
anss = (aa[start]*bb[start] + aa[endd]*bb[endd])%1000000007;
}
#else
anss = 0;
if (start <= endd) {
for(int j=start;j<=endd;j++)anss = add(anss, mul(aa[j], bb[j]));
} else {
for(int j=endd;j<=start;j++)anss = add(anss, mul(aa[j], bb[j]));
}
#endif
cout << anss << endl;
i+= 3;
} else {
start = a[i+1] - 1;
endd = a[i+2];
val = a[i+3];
if(a[i]==1) {
for(int j=start;j<endd;j++) {
#if 0
aa[j] += val;
#else
aa[j] = add(aa[j], val);
#endif
}
} else {
for(int j=start;j<endd;j++) {
#if 0
bb[j] += val;
#else
bb[j] = add(bb[j], val);
#endif
}
}
i+= 4;
}
}
/*
for(int i=0;i<n;i++) {
cout << aa[i] << " " ;
cout << bb[i] << endl;
}
for(int i=0;i<a.size();i++) {
cout << a[i] << endl;
} */
return 0;
}
I was solving a simple problem on spoj called Ambiguous Permutations(http://www.spoj.com/problems/PERMUT2/), it worked fine when I tested for small inputs, but on submission it shows runtime error - segmentation fault. I'm not able to figure it out (though I've wasted a lot of time, and gained frustration only). Please help.
#include <iostream>
#include <stdlib.h>
#include <string.h>
char arr1[200000];//stores original string.
char arr2[200000];//stores inverse permutation.
long int n;
using namespace std;
int main()
{
while (1)
{
cin >> n;
if (n == 0)
{
exit(0);
}
getchar();
gets(arr1);
//creating inverse permutation.
for (long int i = 0; i < 2 * n - 1; i++)
{
if (i % 2 == 1)
{
arr2[i] = ' ';
}
else
{
arr2[2 * (arr1[i] - '0') - 2] = i / 2 + '1';
}
}
arr2[2 * n - 1] = '\0';
//comparing string with it's inverse permutation.
if (strcmp(arr1, arr2) == 0)
{
cout << endl << "ambiguous";
}
else
{
cout << endl << "not ambiguous";
}
}
return 0;
}
The problem is that you are using a char array to represent integers, and your code assumes that each number is represented by one char (note for example checking i % 2 == 1 to determine whether number or space).
Hence, any number bigger than 9 will cause correctness / memory problems.
If you'll use integer arrays it will be a lot easier.
You'll stop worrying about the space character ' ', won't need to decrement '0' char from the cells, and won't need your loops to run till 2 * n - 1.
I think it is much clearer this way:
#include <iostream>
using namespace std;
const int MAX_SIZE = 1000;
int arr1[MAX_SIZE];
int arr2[MAX_SIZE];
int size = 0;
bool areArrsEqual()
{
for (int i = 0; i < size; ++i)
{
if (arr1[i] != arr2[i])
{
return false;
}
}
return true;
}
int main()
{
cin >> size;
while (size > 0 && size <= MAX_SIZE)
{
for (int i = 0; i < size; ++i)
{
cin >> arr1[i];
}
// creating inverse permutation.
for (int i = 0; i < size; i++)
{
// if (arr[i] - 1 >= size) ==> illegal input.
arr2[arr1[i] - 1] = i + 1;
}
// comparing permutation with it's inverse permutation.
if (areArrsEqual())
{
cout << "ambiguous" << endl;
}
else
{
cout << "not ambiguous" << endl;
}
cin >> size;
}
return 0;
}
Output:
4
1 4 3 2
ambiguous
5
2 3 4 5 1
not ambiguous
1
1
ambiguous
13
1 2 3 4 5 6 7 8 9 10 11 12 13
ambiguous
0