This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Algorithm to return all combinations of k elements from n
What I want to do is generate all 1-9 permutations of different length. For example all permutations of length one would simply be
{1}, {2}, {3}, {4} .. and so on.
Permutations of length two would be: {1,2}, {1,3}, {1,4} ..
So far I've been using std::next_permutation(), however it won't do the job in this case.
Is there any way to solve this problem without using recursion? If not and you're providing any code I would really appreciate if you would explain to me, because I'm really struggling with recursion right now, especially with implementing recursive solutions myself. Thanks in advance.
The approach I would use starts from hakmem 175 and that is finding the next higher number with the same number of bits.
So let's say that you code in one int you 10 numbers (from bit 0 to bit 9)
That means that you have to loop from 1 to 10 and prime your start int with the first number that will approximate your pair.
ex: for {1},{2} ... the start int would be 2^0
for {1,2} {1,3} ... the start int would be 2^0+2^1
and so on.
after that you have to make a method that would interpret the number (check if a bit is set then the corresponding number will appear in the sequence).
after that call hakmems method for the next number:
unsigned nexthi(unsigned a) {
unsigned c = (a & -a);
unsigned r = a+c;
return (((r ^ a) >> 2) / c) | r);
}
and continue the loop until no numbers remain.
and go to the next number of bits (1->10)
I suggest looking to hakmem method for you to understand how it works, the implementation is easy if you know a few things about bits.
void permute(std::vector<int>& digits, int length) {
if (length == 0) {
std::cout << "{";
for (int i = 0; i < digits.length; i++) {
std::cout << digits[i] << ",";
}
std::cout << "}" << std::endl;
return;
}
for (int i = 0; i < 9; i++) {
std::vector<int> newDigits(digits);
newDigits.push_back(i);
permute(newDigits, length -1);
}
}
Call this within main as
std::vector<int> digits;
permute(digits, 10); // For 10 digit permutations.
Now if you want to get permutations of length 1,2 ... n, then all you have to do is put the permute function inside a loop.
Note that this is not the most efficient of implementations. But I suppose this should illustrate the recursion clearly.
Related
Hello everyone and thank you for taking your time to answer this very stupid but for me tough question. I have spent so much time trying to figure out how to do this, yet some may find this very simple. The exercise goes like this: "Write the program, that contains a function "numbers", which
will print all four-digit numbers which: all digits are odd and
do not contain a digit 0."
My code is below but if anyone knows how to write a better code than to just correct mine, please share it in the comments.
#include <iostream>
using namespace std;
/* s is the remain when dividing i by 10 */
void numbers ()
{
for (int i = 9999; i >= 1000; i/=10)
{
int s = i % 10;
if (s % 2 == 1 && s != 0)
{
cout << i << endl;
}
i/=10;
}
}
int main()
{
numbers();
return 0;
}
We can approach the problem by analyzing the requirements.
So, we need odd digits. There are only 5 odd digits: 1,3,5,7,9. Any number that we create can consist only of those 5 digits.
The second observation is that there are 5^(NumberOfDigits) different numbers. That is easy to understand. Example: For the first digit, we have 5 possibilities. And then, for each of this 5 digits we have again 5 possible second digits. So, now already 5*5=25 numbers. And for each of the 5 second digits we have again 5 third digits, so, 125 numbers. And for a 4 digit number, we have 5*5*5*5=5^4=625 different numbers.
Good, how to find them? It is obvious, that the delta between two odd digits is 2. Or with other words, if we have an odd digit, we can simply add 2 to get the next odd digit. After the 9, we will have an overflow and need to continue again with 1.
There are many potential designs for the solution.
I will show here an example, were I do not use a complete number, but an array of digits. Then I will add 2 to one digit and if there is an overflow, I will also add 2 to the next digit and so on and so on. Somehow simple.
We do this, until the most significant digit will flip to one, and then all digits are 1 again.
#include <iostream>
#include <array>
#include <algorithm>
#include <iterator>
#include <iomanip>
// Number of digits in a number
constexpr size_t NumberOfDigits = 4u;
// Representation of the number as an array of digits
using Digits = std::array<int, NumberOfDigits>;
// Get the next number/digits
constexpr void nextDigits(Digits& digits) noexcept {
// Starting at the least significant digit
for (int i{ NumberOfDigits-1 }; i >= 0; --i) {
// Get the next odd number
digits[i] += 2;
// Check for overflow, then reset to 1, else stop
if (digits[i] > 9) digits[i] = 1;
else break;
}
}
int main() {
// Define our array with digits and fill it with all one
Digits d{};
std::fill(d.begin(), d.end(), 1);
// Some counter, Just for display purposes
unsigned long long i = 1;
do {
// Some debug output
std::cout << std::right << std::setw(30) << i++ << " --> ";
std::copy(d.begin(), d.end(), std::ostream_iterator<int>(std::cout));
std::cout << '\n';
// And, get the next number/digits
nextDigits(d);
// Do this, until we have found all numbers
} while (not std::all_of(d.begin(), d.end(), [](const int i) {return i == 1; }));
}
Again, this is one of many potential solutions
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Good Evening everyone. I am not really sure as to whether it is against the rules to ask questions like these on this platform (If it is, kindly tell me). The question is of a "practice competition". I could complete 5 of 10 test cases but I am not sure what is wrong in this. Please suggest any correction/logic/hint... And Time Complexity must be less than O(n^2) (According to the input given)
The approach I tried is:
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
signed long int t, n;
scanf("%d", &t);
for (int i = 1; i <= t; i++) {
int count = 0;
scanf("%d", &n);
if (n <= 10)
count = n;
else {
// count = 9;
string s;
s = to_string(n);
int len = s.length();
int x = n / (pow(10, len - 2));
int h = x / 11;
string y = to_string(x);
if (y.length() <= 2)
x = 0;
count = (9 * (len - 1)) + x + h;
}
printf("%d\n", count);
}
return 0;
}
Please suggest whatever you feel is helpful. Thank you so much.
For the problem, given that the work area you are dealing with is relatively small (the number of beautiful numbers less than 10^9 can be reasonably handled with a table of those values), here is a version of a solution that uses a pre-generated table of all of the beautiful numbers in sorted order.
Once the table is set up, it is just a matter of doing a binary search to determine the number of beautiful numbers there are that occur before the input value. The position of the closest beautiful number in the table is the number of beautiful numbers we need.
The binary search is done by utilizing the <algorithm> function std::upper_bound. This function will return an iterator to the item that is greater than the search item. Then to get the position, std::distance is used (we subtract 1, since std::upper_bound will give us the item that is greater than the searched item).
The generation of the table can be done at compile-time (by hand, just initializing an array), or if you're lazy, generated at runtime with a simple loop. Here is one such solution:
#include <algorithm>
#include <vector>
#include <iostream>
std::vector<int> values;
int generate_value(int digit, int numTimes)
{
int total = 0;
for (int i = 0; i < numTimes; ++i)
total = 10 * total + digit;
return total;
}
// I'm lazy, so let the program generate the table for me
void generate_values()
{
size_t curIdx = 0;
values.push_back(0);
for (int i = 1; i <= 9; ++i)
{
for (int j = 1; j <= 9; ++j)
values.push_back(generate_value(j, i));
}
values.push_back(1111111111);
}
// does a binary search and returns the position of the beautiful number
int beautiful(int num)
{
if (num == 0)
return 1;
// get iterator to closest number equaling the beautiful number
auto iter = std::upper_bound(values.begin(), values.end(), num);
// get distance from beginning of vector
return std::distance(values.begin(), iter) - 1;
}
int main()
{
generate_values();
std::cout << beautiful(18) << "\n";;
std::cout << beautiful(1) << "\n";;
std::cout << beautiful(9) << "\n";;
std::cout << beautiful(100500) << "\n";;
std::cout << beautiful(33) << "\n";;
std::cout << beautiful(1000000000) << "\n";;
}
Output:
10
1
9
45
12
81
The size of the table is in total, 83 entries, thus a binary search of this table will take no more than log(83) checks to find the value, which is at most 7 probes in the table.
This is not a complex problem.
Assuming your input is correct so we don’t have to do any checking we observe:
If number n is single digit the number of beautiful numbers is b = n.
If number n is double digit and the first digit is f, then the number of beautiful numbers b = 9 + x, where x is a number of all beautiful double digit numbers smaller than n,
If number n is triple digit and the first digit is f, then the number of beautiful numbers b = 2 x 9 + x, where x is a number of all beautiful triple digit numbers smaller than n.
And so on and on
Thus we can extrapolate: If number n has d digits, than the number of beautiful numbers
s = (d-1) * 9 + x,
where x is a number of beautiful d-digit numbers smaller than or equal to n.
So your problem was reduced to finding x. And this can be reduced even further. Take for instance number n = 44437. The important number here is first digit f. It is trivial to see that all 5 digit beautiful numbers that begin where single digits are less then f are ok. In our example 11111, 22222, 33333 are ok, while 444444 and larger are not.
So all you need to do is to check if beautiful number fffff is smaller than or equal to n. And this can be done with simple traversal of input string.
So your solution would be:
s = (d-1) * 9 + (f-1) + supersecretsauce,
where:
s - solution
n – your input number of age
d – number of digits, assuming your input is always correct is length(n)
f – first digit of your number n
supersecretsauce – 1 if fff…f is smaller or equal than n, 0 if bigger.
And even the traversal of input string can be optimized, but I leave that to you.
Oh yeah... and the time complexity of this solution O(n) = length(n) = log10(n).
A couple of things about the early set up.
1) From the input example you gave, it appears the t and each n need to be input sequentially, but your code prints the number of beautiful numbers before the next input is received. I would suggest reading in t first, then looping through an array of size t to get all the inputs first.
2) The constraints aren't tested. I would test the t and each value in the array mentioned before that the constraints are met, and either have the user try again if they aren't, or simply abort.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Team 7 faces a horrible foe. He can only be defeated with a special
quadruple combination attack of strength ( 1 <=S <= 10^9 ).
Naruto, Sasuke, Sakura and Kakashi must attack simultaneously to
perform the combo. Each of them can choose from N ( 1 <= N <=1000 ) attacks, having strengths si each ( 0 <= i < N, 1 <= si <=10^9). The strengths of individual attacks add up to form the
strength of the combo.
Is there a valid combination that they can use? Note that the same
attacks are available to all of them.
You are required to write a function which takes input as follows – An
integer N as number of attacks, an integer vector s[] as the
strengths of N attacks and an integer S as the required strength
of the combo. Set the output variable to the number of distinct valid
combos.
Two combinations are different if they differ in strength of at least
one attack used.
Input: 1 {1} 4
Output: 1 ===>{1,1,1,1}
Input: 2 {1,2} 5
Output: 1 ===> {1,1,1,2}
Below is my code its only passes 3 test cases out of 10. I don't know the test cases as it was some online code submission.
My Algorithm:
1) Create a hash with indexes as sum of pairs from input array and value as individual elements contributing to sum
2) Iterate over the hash and look if for i in hash there is k-i
3) Count above indexes and return count/2 as we are counting for both H(i) and H(k-i)
Please review the code and tell me what scenarios you think code will not produce right o/p.
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
#include<map>
#include<set>
const int noOfPalyers = 4;
int validCombo(int input1,int input2[],int input3)
{
//Write code here
int count = 0;
std::vector<int> vec;
int size =input1*noOfPalyers;
for(int i = 0; i < input1; i++)
{
for(int j = 0; j < noOfPalyers;j++)
{
vec.push_back(input2[i]);
}
}
std::vector< std::set< std::pair<int, int> > > vecHash;
//vecHash.reserve(size*size);
for(int i =0; i < (size*size); i++)
{
vecHash.push_back(std::set< std::pair<int, int> >());
}
for(int i =0; i < size; i++)
{
for(int j =1; j < size; j++)
{
int key = vec[i] + vec[j];
if(vec[i]<= vec[j])
vecHash[key].insert(std::make_pair(vec[i], vec[j]));
else
vecHash[key].insert(std::make_pair(vec[j], vec[i]));
}
}
for(int i = 0; i < input3; i++)
{
if(vecHash[i].size() > 0 && i < input3)
{
if(vecHash[input3-i].size() > 0)
{
std::set< std::pair<int, int> >::iterator iter, iter2;
for(iter=vecHash[i].begin(); iter!=vecHash[i].end();++iter)
{
for(iter2=vecHash[input3-i].begin(); iter2!=vecHash[input3-i].end();++iter2)
{
std::cout<<(*iter).first<<","<< (*iter).second<<",";
std::cout<<(*iter2).first<<","<< (*iter2).second;
std::cout<<"\n";
count++;
}
}
}
}
}
return (count ==1 ? count: count/2);
}
int main()
{
int i = 3;
int arr[] = {1,2,3};
int j = 7;
int arr1[] ={1};
std::cout <<"o/p == " << validCombo(i, arr, j)<< "\n";
std::cout <<"o/p == " << validCombo(1, arr1, 4);
//getch();
return 0;
}
UPD. My God, now I've understood your comment :) and see that you tried to solve it the same way I wrote. Anyway, I hope you'll find some pieces of my explanation useful. First of all, you don't use hash functions (I know identity function is a hash func, but not the good one in our case). Also I didn't understand your count logic... I think you need to read Two combinations are different if they differ in strength of at least one attack used. part again and check your count logic.
There're just my first thoughts. Hope it could be helpful.
==================================
You know, this problem is about having particular sum of 4 numbers from the set. Let's imagine we have just 2 heroes (so 2 terms in our sum):
a + b = S,
where a, b are attack's strengths from set of N numbers (let's name it T). The number of different a + b sums is N^2. Simple calculating all of these sums and then searching those ones equal to S doesn't give us good solution. This problem can be solved with better complexity.
If we could find a fast function such that:
F(a) = F(S - b)
we would precalculate all F(S - b), then looped over all a's and found which ones satisfy equality above. You mentioned hash. Hash functions can do this. We need such hash func to map all numbers from set T to range [0, N]. Because we just have no more than N different a's.
But we have a little problem here:
F(a) = F(S - b) just means a can be equal to S - b. Fortunately, it's not a big problem,
because the main power is: F(a) != F(S - b) means a != S - b.
Ok, as you see we have algorithm to solve a + b = S problem with amortized O(N) complexity. Sounds good and promising, right? :)
==================================
Now come back to your problem:
a + b + c + d = S
My idea to precalculate all f(a + b) with O(N^2) and store them like this (warning! just pseudocode):
vector<int> hash = new vector<int>(with size N)
foreach (a in T)
foreach (b in T)
{
int x = OurHashFunc(a + b); // a + b <= 2 * 10^9 so it never overflows int
if (hash[x] == null)
hash[x] = new vector<pair<int,int>>
hash[x].push_back(new pair<int, int>(a, b));
}
We keep pairs (a,b) to be able to restore terms of initial sum. Then if our OurHashFunc is additive then transform our initial problem like this:
a + b + c + d = S // apply hash func =>
f(a + b) + f(c + d) = f(S) // rename =>
x + y = Z // wow, I bet I've already seen this equation ;)
Now 4-terms sum problem had reduced to 2-terms sum problem with an O(N^2) overhead.
I think this reduction can be continued: 2^k-terms sum problem should have avg O(N^k) solution.
I am taking part in an online programming contest for fun on http://www.hackerrank.com. One of the problems that I am working on is to find number of anagrams of a string that are palindrome as well. I have solve the problem but when I try to upload it it fails on a number of test cases. As the actual test cases are hidden from me I do not know for sure why its failing but I assume it could be a scalability issue. Now I do not want someone to give me a ready made solution because that would not be fair but I am just curious on what people think about my approach.
Here is the problem description from the website:
Now that the king knows how to find out whether a given word has an anagram which is a palindrome or not, he is faced with another challenge. He realizes that there can be more than one anagram which are palindromes for a given word. Can you help him find out how many anagrams are possible for a given word which are palindromes?
The king has many words. For each given word, the king needs to find out the number of anagrams of the string which are palindromes. As the number of anagrams can be large, the king needs number of anagrams % (109+ 7).
Input format :
A single line which will contain the input string
Output format :
A single line containing the number of anagram strings which are palindrome % (109 + 7).
Constraints :
1<=length of string <= 105
Each character of the string is a lowercase alphabet.
Each testcase has atleast 1 anagram which is a palindrome.
Sample Input 01 :
aaabbbb
Sample Output 01 :
3
Explanation :
Three permutation of given string which are palindrome can be given as abbabba , bbaaabb and bababab.
Sample Input 02 :
cdcdcdcdeeeef
Sample Output 02 :
90
As specified in the problem description input strings can be as large as 10^5, hence all palindromes for a large string is not possible since I will run into number saturation issues. Also since I only need to give a modulo (10^9 + 7) based answer, I thought of taking log of numbers with base (10^9 + 7) and after all computations take antilog of fraction part with base (10^9 + 7) of the answer since that will be the modulo anyway.
My algorithm is as follows:
Store freq of each char (only need to look half of the string since
second half should be same as first one by def of palindrome)
If there are more than one char appearing with odd number of time no palindrome possible
Else for each char's freq incrementally calculate number of palindromes (Dynamic Programming)
For the DP following is the subproblem:
previous_count = 1
For each additional character added number of palindromes = previous_count * (number_of_char_already_seen + 1)/(number of char same as current char)
Here is my code:
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <fstream>
using namespace std;
#define MAX_SIZE 100001
void factorial2 (unsigned int num, unsigned int *fact) {
fact[num]++;
return;
}
double mylog(double x) {
double normalizer = 1000000007.0;
return log10(x)/log10(normalizer);
}
int main() {
string in;
cin >> in;
if (in.size() == 1) {
cout << 1 << endl;
return 0;
}
map<char, int> freq;
for(int i=0; i<in.size(); ++i) {
if (freq.find(in.at(i)) == freq.end()) {
freq[in.at(i)] = 1;
} else {
freq[in.at(i)]++;
}
}
map<char, int> ::iterator itr = freq.begin();
unsigned long long int count = 1;
bool first = true;
unsigned long long int normalizer = 1000000007;
unsigned long long int size = 0;
unsigned int fact[MAX_SIZE] = {0};
vector<unsigned int> numerator;
while (itr != freq.end()) {
if (first == true) {
first = false;
} else {
for (size_t i=1; i<=itr->second/2; ++i) {
factorial2(i, fact);
numerator.push_back(size+i);
}
}
size += itr->second/2;
++itr;
}
//This loop is to cancel out common factors in numerator and denominator
for (int i=MAX_SIZE-1; i>1; --i) {
while (fact[i] != 0) {
bool not_div = true;
vector<unsigned int> newNumerator;
for (size_t j=0; j<numerator.size(); ++j) {
if (fact[i] && numerator[j]%i == 0) {
if (numerator[j]/i > 1)
newNumerator.push_back(numerator[j]/i);
fact[i]--; //Do as many cancellations as possible
not_div = false;
} else {
newNumerator.push_back(numerator[j]);
}
}
numerator = newNumerator;
if (not_div) {
break;
}
}
}
double countD = 0.0;
for (size_t i=0; i<numerator.size(); ++i) {
countD += mylog(double(numerator[i]));
}
for (size_t i=2; i <MAX_SIZE; ++i) {
if (fact[i]) {
countD -= mylog((pow(double(i), double(fact[i]))));
fact[i] = 0;
}
}
//Get the fraction part of countD
countD = countD - floor(countD);
countD = pow(double(normalizer), countD);
if (floor(countD + 0.5) > floor(countD)) {
countD = ceil(countD);
} else {
countD = floor(countD);
}
count = countD;
cout << count;
return 0;
}
Now I have spent a lot of time on this problem and I just wonder if there is something wrong in my approach or am I missing something here. Any ideas?
Note that anagrams are reflexive (they look the same read from the back as from the front), so half the occurrences of each character will be on one side and we just need to calculate the number of permutations of these. The other side will be an exact reversal of this side, so it doesn't add to the number of possibilities. The odd occurrence of a character (if one exists) must always be in the middle, so it can be ignored when calculating the number of permutations.
So:
Calculate the frequencies of the characters
Check that there's only 1 odd frequency
Divide the frequency of each character (rounding down - removes any odd occurrence).
Calculate the permutation of these characters using this formula:
(as per Wikipedia - multiset permutation)
Since the above terms can get quite big, we might want to split the formula up into prime factors so we can cancel out terms so we're left with only multiplication, then I believe we can % 109 + 7 after each multiplication, which should fit into a long long (since (109+7)*105 < 9223372036854775807).
Thanks to IVlad for pointing out a more efficient method of avoiding overflow than above:
Notice that p = 109 + 7 is a prime number, so we can use Fermat's little theorem to compute the multiplicative inverses of the mi mod p, and multiply by these and take the mod at each step instead of dividing. mi-1 = mi(10^9 + 5) (mod p). Using exponentiation by squaring, this will be very fast.
I also found this question (which also has some useful duplicates).
Examples:
Input: aaabbbb
Frequency:
a b
3 4
Div 2:
a b
1 2
Solution:
3!/2!1! = 3
Input: cdcdcdcdeeeef
Frequency:
c d e f
4 4 4 1
Div 2:
c d e f
2 2 2 0
Solution:
6!/2!2!2!0! = 90
The basic formula is:
p!/(a!*b!...*z!)
where p is floor of length/2 of the word and a,b,c..,z denotes the floor of half of frequency of occurrences a,b,c..,z in the word receptively.
The only problem now you are left is how to calculate this. For that, check this out.
I'm working on Euler Problem 14:
http://projecteuler.net/index.php?section=problems&id=14
I figured the best way would be to create a vector of numbers that kept track of how big the series was for that number... for example from 5 there are 6 steps to 1, so if ever reach the number 5 in a series, I know I have 6 steps to go and I have no need to calculate those steps. With this idea I coded up the following:
#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
int main()
{
vector<int> sizes(1);
sizes.push_back(1);
sizes.push_back(2);
int series, largest = 0, j;
for (int i = 3; i <= 1000000; i++)
{
series = 0;
j = i;
while (j > (sizes.size()-1))
{
if (j%2)
{
j=(3*j+1)/2;
series+=2;
}
else
{
j=j/2;
series++;
}
}
series+=sizes[j];
sizes.push_back(series);
if (series>largest)
largest=series;
cout << setw(7) << right << i << "::" << setw(5) << right << series << endl;
}
cout << largest << endl;
return 0;
}
It seems to work relatively well for smaller numbers but this specific program stalls at the number 113382. Can anyone explain to me how I would go about figuring out why it freezes at this number?
Is there some way I could modify my algorithim to be better? I realize that I am creating duplicates with the current way I'm doing it:
for example, the series of 3 is 3,10,5,16,8,4,2,1. So I already figured out the sizes for 10,5,16,8,4,2,1 but I will duplicate those solutions later.
Thanks for your help!
Have you ruled out integer overflow? Can you guarantee that the result of (3*j+1)/2 will always fit into an int?
Does the result change if you switch to a larger data type?
EDIT: The last forum post at http://forums.sun.com/thread.jspa?threadID=5427293 seems to confirm this. I found this by googling for 113382 3n+1.
I think you are severely overcomplicating things. Why are you even using vectors for this?
Your problem, I think, is overflow. Use unsigned ints everywhere.
Here's a working code that's much simpler and that works (it doesn't work with signed ints however).
int main()
{
unsigned int maxTerms = 0;
unsigned int longest = 0;
for (unsigned int i = 3; i <= 1000000; ++i)
{
unsigned int tempTerms = 1;
unsigned int j = i;
while (j != 1)
{
++tempTerms;
if (tempTerms > maxTerms)
{
maxTerms = tempTerms;
longest = i;
}
if (j % 2 == 0)
{
j /= 2;
}
else
{
j = 3*j + 1;
}
}
}
printf("%d %d\n", maxTerms, longest);
return 0;
}
Optimize from there if you really want to.
When i = 113383, your j overflows and becomes negative (thus never exiting the "while" loop).
I had to use "unsigned long int" for this problem.
The problem is overflow. Just because the sequence starts below 1 million does not mean that it cannot go above 1 million later. In this particular case, it overflows and goes negative resulting in your code going into an infinite loop. I changed your code to use "long long" and this makes it work.
But how did I find this out? I compiled your code and then ran it in a debugger. I paused the program execution while it was in the loop and inspected the variables. There I found that j was negative. That pretty much told me all I needed to know. To be sure, I added a cout << j; as well as an assert(j > 0) and confirmed that j was overflowing.
I would try using a large array rather than a vector, then you will be able to avoid those duplicates you mention as for every number you calculate you can check if it's in the array, and if not, add it. It's probably actually more memory efficient that way too. Also, you might want to try using unsigned long as it's not clear at first glance how large these numbers will get.
i stored the length of the chain for every number in an array.. and during brute force whenever i got a number less than that being evaluated for, i just added the chain length for that lower number and broke out of the loop.
For example, i already know the Collatz sequence for 10 is 7 lengths long.
now when i'm evaluating for 13, i get 40, then 20, then 10.. which i have already evaluated. so the total count is 3 + 7.
the result on my machine (for upto 1 million) was 0.2 secs. with pure brute force that was 5 seconds.