Cannot determine why output is wrong while rotating vector - c++

I have written the following code -
#include <cassert>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
using namespace std;
vector<int> v;
int main()
{
int n, d, i = 0;
cin >> n >> d;
assert(n >= 1 && n <= 100000 && d >= 1 && d <= n);
int temp = 0;
for (int i = 0; i < n; i++)
{
cin >> temp;
v.push_back(temp);
}
reverse(v.begin(), v.begin() + d - 1);
reverse(v.begin() + d, v.end());
reverse(v.begin(), v.end());
for (i = 0; i < n; i++)
cout << v[i] << " ";
return 0;
}
Now, the problem is that when I enter the following input -
5 4
1 2 3 4 5
it doesn't give me the correct output 5 1 2 3 4 but rather gives me this 5 4 1 2 3
Any idea what might be wrong?

The output of the program is correct, for that input. It is your expectations that are incorrect.
The thing to realise is that standard algorithms do not dereference specified end iterators. So reverse(v.begin(), v.begin() + 3) will reverse the first three elements of v (i.e. v[0] through to v[2]) not the first four.
So the first reverse() reverses the first three elements, producing the order 3 2 1 4 5.
To get the results you expect, it would be reversing the first four.

Related

Getting unknown values along with answer

Smaller Greater Equal Numbers
PrepBuddy has N baskets containing one fruit each with some quality factor(ith basket have Ai quality factor) and Tina has one single basket with one fruit having quality factor K. She wants to know how many PrepBuddy's baskets have quality factor less(L) than K, how many baskets have quality factor more(M) than K and how many baskets have quality factor equal(E) to K.
Input format
The first line contains an integer T, representing the number of test cases.T test cases follow,First linecontains two space-separated integers N and K.The second line contains N space-separated integers representing the quality factor of the basket.
Output format
For each test case on a new line, print three space-separated integers representing the values of L, M,and E.
Constraints
1<=T<=100
1<=N,K<=10^5
−10^6<=A[i]<=10^6
Sum of all N over any test case file doesn't exceed 5∗10^6
Time Limit
1 second
Example
Input
2
5 2
-1 0 -3 1 2
5 3
1 -1 -5 2 4
Output
4 0 1
4 1 0
Sample test case explanation
In the first test case,
K=2, the baskets with quality factor smaller than K are [1,2,3,4], there is no basket which has quality factor more than K and there is one basket [5] which have quality factor equal to K.
My solution
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
ll n, k;
cin >> n >> k;
ll arr[n];
for (ll i = 0; i < n; i++) {
cin >> arr[i];
}
int less = 0, more = 0, equal = 0;
for (ll i = 0; i < n; i++) {
if (arr[i] < k) {
less++;
} else if (arr[i] > k) {
more++;
} else {
equal++;
}
cout << less << " " << more << " " << equal << " ";
}
cout << endl;
}
return 0;
}
Input
2
5 2
-1 0 -3 1 2
5 3
1 -1 -5 2 4
Output
1 0 0 2 0 0 3 0 0 4 0 0 4 0 1
1 0 0 2 0 0 3 0 0 4 0 0 4 1 0
Why am I getting additional numbers like 1 0 0 2 0 0 3 0 0 4 0 0 along with my answer.How to correct this?? Please help
The error in your code was quiet simple, and easy to debug. You were printing the output every run through the array, thus, getting all these extra prints.
How does it become easy to debug? Reorganizing the code so it will be more readable, made it quiet possible. Actually, the fix was moving the line:
cout<<less<<" "<<more<<" "<<equal<<" ";
Two line lower than it was.
In order to demonstrate it, here is the code fixed and organized:
#include <iostream>
#include <vector>
#include <cstdint>
int main()
{
int t;
std::cin >> t;
while(t--)
{
std::int64_t n,k;
std::cin >> n >> k;
std::vector<int> vec{n};
for(std::size_t i = 0; i < n; ++i)
{
std::cin >> vec[i];
}
int less=0, more=0, equal=0;
for (std::size_t i = 0; i < n; i++)
{
if (vec[i] < k)
{
less++;
}
else if (vec[i] > k)
{
more++;
}
else
{
equal++;
}
// The next output line was here, under the for loop!!!
}
std::cout << less << " " << more<< " " << equal << " "; // this is its place!
std::cout << std::endl;
}
return 0;
}
I have made only 3 changes:
Removed the using namespace std; and #include <bit/stdc++.h>.
Realigned the code according to its logical order - each new scope has its own indentation level, showing which command runs in which scope, revealing the mistake.
Used proper types to each thing: In C++ there are no dynamic arrays in the format arr[n], thus, you need to use std::vector. Also, there are fixed size lengths in cstdint, and you should use those to ensure you are using the right type. Also, prefer using unsigned values when possible, for example, when indexing, use either std::size_t, std::uint32_t or std::uint64_t.
This code worked fine for me
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T,N,K,arr[N];
cin>>T;
while(T--)
{
cin>>N;
cin>>K;
for(int i=0;i<N;i++)
{
cin>>arr[i];
}
int L=0,M=0,E=0;
for(int i=0;i<N;i++)
{
if(arr[i]<K){
L++;
}
else if(arr[i]>K)
{
M++;
}
else{
E++;
}
}
cout<<L<<" "<<M<<" "<<E<<endl;
}
return 0;
}

Finding if 1 vector is included in 2nd vector

I need to write a program that finds out if one of the 2 vector is included in another one.
The program works like this.
1 - Gets the m and n values from input.txt (1st row)
2 - Resizes verctorM and vectorN to m and n, then fills them with numbers from input.txt (2nd row for vectorM, 3rd row for vectorN)
3 - After filling, the program should find out wich one of the vectors has the fewest "characters" by comparing n and m
4 - The program gets the first "character" of "small" vector and start to compare it with the "characters" of "big" vector ()
5 - When the statemant vectorN[i] = vectorM[0] is correct, the program compares the next "characters" if every "character" of "small" vector is in the "big" vector, program output 1, if not continues to compare with 1st "caracter" of "smal" vector, if "small" vector is not included in "big" vector, program outputs 0
Edit - the numbers must be in same order as written in input.txt
Here is the code that I ended up with
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
int main() {
int m;
int n;
bool y = false;
vector<int> vectorM;
vector<int> vectorN;
ifstream file1;
file1.open("input.txt");
file1 >> m;
file1 >> n;
vectorM.resize(m);
vectorN.resize(n);
for (int i = 0; i < m; i++){
file1 >> vectorM[i];
}
for (int i = 0; i < n; i++){
file1 >> vectorN[i];
}
//this is the part that I need help with
ofstream file2;
file2.open("output.txt");
if (y == false)
file2 << 0;
else
file2 << 1;
}
What's the efficent way to compare the "characters" ??
Example, if in input.txt
4 3
1 2 3 2
1 2 3
Program outputs 1, because 1 2 3 is in 1 2 3 2, but if
2 3
1 2
2 3 1
Program outputs 0
I think you're asking if a contiguous subsequence can be found inside another range of values. The standard library std::search algorithm does just that.
#include <algorithm>
#include <iostream>
#include <vector>
bool included(const std::vector<int>& seq, const std::vector<int>& sub)
{
return std::search(seq.begin(), seq.end(), sub.begin(), sub.end()) != seq.end();
}
int main()
{
auto v1 = std::vector<int>{ 1,2,3,2 };
auto v2 = std::vector<int>{ 1,2,3 };
std::cout << std::boolalpha << included(v1, v2) << '\n';
auto v3 = std::vector<int>{ 1,2 };
auto v4 = std::vector<int>{ 2,3,1 };
std::cout << included(v3, v4) << '\n';
}
Demo on ideone.com
Note: I stole Jarod42's function name and coincoin's test data.

TIME_LIMIT_EXCEEDED at Codeforces 558E

I am beginner in the programming field and I have started to solve problems on Codeforces and this is my first problem on it and when I submit this problem solution A Simple Task with this code
#include <iostream>
#include <string>
using namespace std;
void swapchar(char &x, char &y)
{
char temp;
temp = x;
x = y;
y = temp;
}
void main()
{
string s;
long n, q;
long i, j;
bool k;
cin >> n >> q;
cin >> s;
for (int x = 0; x<q; x++)
{
cin >> i >> j >> k;
if (i<1 || j<1 || i>n || j>n)
break;
if (k == 1)
{
for (int u = i - 1; u < j; u++)
{
for (int v = u + 1; v < j; v++)
{
if (s[u] > s[v])
swapchar(s[u], s[v]);
}
}
}
else if (k == 0)
for (int u = i - 1; u < j; u++)
{
for (int v = u + 1; v < j; v++)
{
if (s[u] < s[v])
swapchar(s[u], s[v]);
}
}
}
cout << s << endl;
}
then the codeforces' output is :-
Time limit exceeded on test 6
and when i searched about what it is the test 6 i found :-
Test: #6, time: 5000 ms., memory: 12 KB, exit code: -1, checker exit code: 0, verdict: TIME_LIMIT_EXCEEDED
Input
2256 44182
kanqevxwgecliptqmdsgnflqyohgtukphlbmjxndbtjqujuafxankfghlseytdwdviamqjscacuyrghriuaihxtyersgnyvigenpflwequgbdusnvlgplxjxkqhjbdvkmufpoirqueufblnnrnbhmcnvewzfdonwjgswuneimtykntwgrlfqlvkdblwjzplhffzqpopbjmvrjcxyzgxqhkjbrgdqnipsipexpoozphfrgzboiiiskawtbhegerhvknrzljclhnpokpazhspsmzeiujddlpfireoyjzriickcuwtbimxjbhunedcdgaabztczkzmahnriarzcmnkjrrfqkodxbpocmxjvutpqbmawcsghwxdidhmwbfxuqegpjtqfvaloycogvoxdtjotlknazaeofaxlomeywwlezlndhpjwbgpxgkvubropxffytucvlbhjugzqgglrezoqsrvwkdrbuehbjxtgobugghqrgbgacqi...
I don't know what does that problem mean and how to solve it
Please explain and help me.
You're using a selection sort (with a few superfluous swaps) that's O(n^2) complexity, try using std::sort instead. You don't have too much to change in your code:
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{
string s;
long n, q;
long i, j;
bool k;
cin >> n >> q;
cin >> s;
for (int x = 0; x<q; x++)
{
cin >> i >> j >> k;
if (i<1 || j<1 || i>n || j>n)
break;
if (k == 1)
{
std::sort(s.begin() + i-1, s.begin() + j);
}
else if (k == 0)
std::sort(s.begin() + i-1, s.begin() + j, std::greater<char>());
}
cout << s << endl;
}
std::sort(s.begin() + i-1, s.begin() + j); sorts from s.begin() + i-1 up to but not includings.begin() + j. The second just sorts in reverse order by using > (std::greater) instead of < for comparison. Note the #include <algorithm> for the std::sort and #include <functional> for std::greater.
Note that I got rid of your swapchar function since we don't need it anymore, I also changed the return type of main to int as it's supposed to be.
The above code manages to handle the test 6 that you had problems with but exceeds time limit for test 9 (I even tried some small other changes there).
To complete tests 9+ you're probably supposed to think a bit more about the problem and possible input, take for example the following sort queries:
20 57 1
89 950 1
57 100 0
57 100 1
1 9500 0
Here we'd do tons of useless sorting and I wouldn't be surprised if the 9th problem were to test if you identified this. First we sort the range [20, 57] and [89, 950] in ascending order, then we sort the range [57, 100] in descending order and resorting the same range in ascending order right afterwards overriding the first one completely. Lastly we sort the range [1, 9500] in descending order, overwriting all the previous sorts which we could have completely left out since they're overwritten anyways.
We could make use of the knowledge that later sorts can and likely will override previous ones. We could first save all the "sort queries" we were given and later start with the last one (since that one would override all previous ones anyways) and go in reverse order only sorting the ranges we haven't sorted yet. That way we can get rid of lots of useless sorting that we'd otherwise do even though we'd later overwrite it and speeding it up a lot.

Find the amount of changes in the sign of number in an array

Basically, I have an array given of "x" numbers and I have to output the amount of how many times the sign changed in the numbers of the array.
For example array is:
2 -4 5 6 7 -2 5 -7
The output should be 5. Why? Because the sign changes first time at -4, second time at 5, third time at -2, fourth time at 5 and last time at -7. Total 5 times.
So, I have this so far but that doesn't work perfectly:
#include <iostream>
using namespace std;
int main()
{
int a[50],n,cs=0,ha=0;
cin >> n;
for (int i=0;i<n;i++)
{
cin >> a[i];
}
for (int j=1;j<=n;j++)
{
if(a[j]<0 && a[j-1]>0)
cs++;
else if(a[j]>0 && a[j-1]<0)
cs++;
}
cout << cs << endl;
return 0;
}
Please help!
Your problem is that you're running into uninitialized memory, which is causing undefined behaviour. You initialize a[0] through a[n-1] in your input loop and then read from a[0] (with j=1 and a[j-1]) to a[n] (j=n and a[j]) in your calculation loop.
Simply change it to j < n.
If STL is an option for you, you can use std::adjacent_find. This is how you would use it in a complete program:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> v { 1 , 3, -5, 8, -9, -10, 4 };
auto signSwitch = [] (int x, int y) { return (abs(x) == x) ^ (abs(y) == y); };
int cnt = 0;
auto i = adjacent_find(begin(v), end(v), signSwitch);
while (i != end(v))
{
cnt++;
i = adjacent_find(i + 1, end(v), signSwitch);
}
cout << cnt;
}
Your second loop should terminate at j < n.
On your second for loop you should not have j go to <=. it should just be
for (int j=1;j<n;j++)

Find subsequences of a string whose length is as large as 10,000

I have a string whose size can be as large as "10,000". I have to count those SUBSEQUENCES which are divisible by 9.
SUBSEQUENCE: A subsequence is an arrangement in which the order of characters of given string is maintained. For ex: if given string is 10292 then some of its subsequences are 1, 102, 10, 19, 12, 12(12 is twice as 2 comes twice), 129, 029, 09, 092, etc. Some numbers which are not subsequences of given string are: 201(2 and 0 can't come before 1), 921, 0291, etc.
I have tried to generate all subsequences(powerset) of given string using bit shifting and checking each string if it is divisible by 9. But this works fine as long as length of string is <=10. After that, I don't get proper subsequences(some subsequences are displayed negative numbers).
Below is my code:
scanf("%s", &str); //input string
int n=strlen(str); //find length of string
//loop to generate subsequences
for(i=1;i<(1<<n);++i){
string subseq;
for(j=0;j<n;++j){
if(i&(1<<j)){
subseq+=str[j]; // generate subsequence
}
}
//convert generated subseq to int; number is 'long' tpye
number=atol(subseq.c_str());printf("%ld\n", number);
//ignore 0 and check if number divisible by 9
if(number!=0&&number%9==0)count++;
}
printf("%ld\n", count);
Since a number is divisible by nine if and only if the sum of its digits is divisible by nine, you can get away with this problem with a O(n) recursive algorithm.
The idea is the following: at each step, split in two the subsequence and determine (recursively) how many sequences have the sum of its digits be i % 9, where i ranges from 0 to 8. Then, you build up this very same table for the whole range by "merging" the two tables in O(1) in the following way. Let's say L is the table for the left split and R for the right one and you need to build the table F for the whole range.
Then you have:
for (i = 0; i < 9; i++) {
F[i] = L[i] + R[i];
for (j = 0; j < 9; j++) {
if (j <= i)
F[i] += L[j] * R[i - j]
else
F[i] += L[j] * R[9 + i - j]
}
}
The base case for a subsequence of only one digit d is obvious: just set F[d % 9] = 1 and all the other entries to zero.
A full C++11 implementation:
#include <iostream>
#include <array>
#include <tuple>
#include <string>
typedef std::array<unsigned int, 9> table;
using std::tuple;
using std::string;
table count(string::iterator beg, string::iterator end)
{
table F;
std::fill(F.begin(), F.end(), 0);
if (beg == end)
return F;
if (beg + 1 == end) {
F[(*beg - '0') % 9] = 1;
return F;
}
size_t distance = std::distance(beg, end);
string::iterator mid = beg + (distance / 2);
table L = count(beg, mid);
table R = count(mid, end);
for (unsigned int i = 0; i < 9; i++) {
F[i] = L[i] + R[i];
for(unsigned int j = 0; j < 9; j++) {
if (j <= i)
F[i] += L[j] * R[i - j];
else
F[i] += L[j] * R[9 + i - j];
}
}
return F;
}
table count(std::string s)
{
return count(s.begin(), s.end());
}
int main(void)
{
using std::cout;
using std::endl;
cout << count("1234")[0] << endl;
cout << count("12349")[0] << endl;
cout << count("9999")[0] << endl;
}
I had an idea!
Since you only have to count the substrings, you don't care what they actually are. So instead, you can just store counts of their possible sums.
Then, what if you had a function that could combine the count tables of two substring sets, and give you the counts of their combinations?
And since I know that was a horrible explanation, I'll give an example. Say you're given the number:
2493
Split it in half and keep splitting until you get individual digits:
2493
/ \
24 93
/\ /\
2 4 9 3
What can 2 sum to? Easy: 2. And 4 can only sum to 4. You can build tables of how many substrings sum to each value (mod 9):
0 1 2 3 4 5 6 7 8
2: 0 0 1 0 0 0 0 0 0
4: 0 0 0 0 1 0 0 0 0
9: 1 0 0 0 0 0 0 0 0
3: 0 0 0 1 0 0 0 0 0
Combining two tables is easy. Add the first table, the second table, and every combination of the two mod 9 (for the first combination, this is equivalent to 2, 4, and 24; for the second, 9, 3, and 93):
0 1 2 3 4 5 6 7 8
24: 0 0 1 0 1 0 1 0 0
93: 1 0 0 2 0 0 0 0 0
Then do it again:
0 1 2 3 4 5 6 7 8
2493: 3 0 2 2 2 2 2 2 0
And there's your answer, sitting there in the 0 column: 3. This corresponds to the substrings 243, 2493, and 9. You don't know that, though, 'cause you only stored counts - and fortunately, you don't care!
Once implemented, this'll give you O(n) performance - you'll just have to figure out exactly how to combine the tables in O(1). But hey - homework, right? Good luck!
If you use int then you shouldnt left shift it too much. If you do, you set the sign bit. Use unsigned int. Or dont left shift too much. You can rightshift once you done if you insist on int.
for the
printf("%ld\n", count);
printf could have problems at displaying long-int types. Did you try cout ?
Here's C++ code according to Akappa's algorithm. However this algorithm fails for numbers that contain one or more 0s i.e. in cases of "10292" and "0189" but gives correct answers for "1292" ans "189". Would appreciate it if anyone could debug this to give answers for all cases.
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<string>
#include<cstring>
#include<vector>
#include<stack>
#include<sstream>
#include<algorithm>
#include<cctype>
#include<list>
#include<set>
#include<set>
#include<map>
using namespace std;
typedef vector<int> table;
table count(string::iterator beg, string::iterator end)
{
table F(9);
std::fill(F.begin(), F.end(), 0);
if (beg == end)
return F;
if (beg + 1 == end) {
F[(*beg - '0') % 9] = 1;
return F;
}
size_t distance = std::distance(beg, end);
string::iterator mid = beg + (distance / 2);
table L = count(beg, mid);
table R = count(mid, end);
for (unsigned int i = 0; i < 9; i++) {
F[i] = L[i] + R[i];
for(unsigned int j = 0; j < 9; j++) {
if (j <= i)
F[i] += L[j] * R[i - j];
else
F[i] += L[j] * R[9 + i - j];
}
}
return F;
}
table count(std::string s)
{
return count(s.begin(), s.end());
}
int main()
{
cout << count("1234")[0] << endl;
cout << count("12349")[0] << endl;
cout << count("9999")[0] << endl;
cout << count("1292")[0] << endl;cout << count("189")[0] << endl;
cout << count("10292")[0] << endl;cout << count("0189")[0] << endl;
system("pause");
}