How do I proceed with a question like this? [closed] - c++

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.

Related

Can someone please explain this bit manipulation code to me?

I am new to competitive programming. I recently gave the Div 3 contest codeforces. Eventhough I solved the problem C, I really found this code from one of the top programmers really interesting. I have been trying to really understand his code, but it seems like I am too much of a beginner to understand it without someone else explaining it to me.
Here is the code.
void main(){
int S;
cin >> S;
int ans = 1e9;
for (int mask = 0; mask < 1 << 9; mask++) {
int sum = 0;
string num;
for (int i = 0; i < 9; i++)
if (mask >> i & 1) {
sum += i + 1;
num += char('0' + (i + 1));
}
if (sum != S)
continue;
ans = min(ans, stoi(num));
}
cout << ans << '\n';
}
The problem is to find the minimum number whose sum of digits is equal to given number S, such that every digit in the result is unique.
Eq. S = 20,
Ans = 389 (3+8+9 = 20)
Mask is 9-bits long, each bit represents a digit from 1-9. Thus it counts from 0 and stops at 512. Each value in that number corresponds to possible solution. Find every solution that sums to the proper value, and remember the smallest one of them.
For example, if mask is 235, in binary it is
011101011 // bit representation of 235
987654321 // corresponding digit
==> 124678 // number for this example: "digits" with a 1-bit above
// and with lowest digits to the left
There are a few observations:
you want the smallest digits in the most significant places in the result, so a 1 will always come before any larger digit.
there is no need for a zero in the answer; it doesn't affect the sum and only makes the result larger
This loop converts the bits into the corresponding digit, and applies that digit to the sum and to the "num" which is what it'll print for output.
for (int i = 0; i < 9; i++)
if (mask >> i & 1) { // check bit i in the mask
sum += i + 1; // numeric sum
num += char('0' + (i + 1)); // output as a string
}
(mask >> i) ensures the ith bit is now shifted to the first place, and then & 1 removes every bit except the first one. The result is either 0 or 1, and it's the value of the ith bit.
The num could have been accumulated in an int instead of a string (initialized to 0, then for each digit: multiply by 10, then add the digit), which is more efficient, but they didn't.
The way to understand what a snippet of code is doing is to A) understand what it does at a macro-level, which you have done and B) go through each line and understand what it does, then C) work your way backward and forward from what you know, gaining progress a bit at a time. Let me show you what I mean using your example.
Let's start by seeing, broadly (top-down) what the code is doing:
void main(){
// Set up some initial state
int S;
cin >> S;
int ans = 1e9;
// Create a mask, that's neat, we'll look at this later.
for (int mask = 0; mask < 1 << 9; mask++) {
// Loop state
int sum = 0;
string num;
// This loop seems to come up with candidate sums, somehow.
for (int i = 0; i < 9; i++)
if (mask >> i & 1) {
sum += i + 1;
num += char('0' + (i + 1));
}
// Stop if the sum we've found isn't the target
if (sum != S)
continue;
// Keep track of the smallest value we've seen so far
ans = min(ans, stoi(num));
}
// Print out the smallest value
cout << ans << '\n';
}
So, going from what we knew about the function at a macro level, we've found that there are really only two spots that are obscure, the two loops. (If anything outside of those are confusing to you, please clarify.)
So now let's try going bottom-up, line-by-line those loops.
// The number 9 appears often, it's probably meant to represent the digits 1-9
// The syntax 1 << 9 means 1 bitshifted 9 times.
// Each bitshift is a multiplication by 2.
// So this is equal to 1 * (2^9) or 512.
// Mask will be 9 bits long, and each combination of bits will be covered.
for (int mask = 0; mask < 1 << 9; mask++) {
// Here's that number 9 again.
// This time, we're looping from 0 to 8.
for (int i = 0; i < 9; i++) {
// The syntax mask >> i shifts mask down by i bits.
// This is like dividing mask by 2^i.
// The syntax & 1 means get just the lowest bit.
// Together, this returns true if mask's ith bit is 1, false if it's 0.
if (mask >> i & 1) {
// sum is the value of summing the digits together
// So the mask seems to be telling us which digits to use.
sum += i + 1;
// num is the string representation of the number whose sum we're finding.
// '0'+(i+1) is a way to convert numbers 1-9 into characters '1'-'9'.
num += char('0' + (i + 1));
}
}
}
Now we know what the code is doing, but it's hard to figure out. Now we have to meet in the middle - combine our overall understanding of what the code does with the low-level understanding of the specific lines of code.
We know that this code gives up after 9 digits. Why? Because there are only 9 unique non-zero values (1,2,3,4,5,6,7,8,9). The problem said they have to be unique.
Where's zero? Zero doesn't contribute. A number like 209 will always be smaller than its counterpart without the zero, 92 or 29. So we just don't even look at zero.
We also know that this code doesn't care about order. If digit 2 is in the number, it's always before digit 5. In other words, the code doesn't ever look at the number 52, only 25. Why? Because the smallest anagram number (numbers with the same digits in a different order) will always start with the smallest digit, then the second smallest, etc.
So, putting this all together:
void main(){
// Read in the target sum S
int S;
cin >> S;
// Set ans to be a value that's higher than anything possible
// Because the largest number with unique digits is 987654321.
int ans = 1e9;
// Go through each combination of digits, from 1 to 9.
for (int mask = 0; mask < 1 << 9; mask++) {
int sum = 0;
string num;
for (int i = 0; i < 9; i++)
// If this combination includes the digit i+1,
// Then add it to the sum, and append to the string representation.
if (mask >> i & 1) {
sum += i + 1;
num += char('0' + (i + 1));
}
// If this combination does not yield the right sum, try the next combination.
if (sum != S)
continue;
// If this combination does yield the right sum,
// see if it's smaller than our previous smallest.
ans = min(ans, stoi(num));
}
// Print the smallest combination we found.
cout << ans << '\n';
}
I hope this helps!
The for loop is iterating over all 9-digit binary numbers and turning those binary numbers into a string of decimal digits such that if nth binary digit is on then a n+1 digit is appended to the decimal number.
Generating the numbers this way ensures that the digits are unique and that zero never appears.
But as #Welbog mentions in comments this solution to the problem is way more complicated than it needs to be. The following will be an order of magnitude faster, and I think is clearer:
int smallest_number_with_unique_digits_summing_to_s(int s) {
int tens = 1;
int answer = 0;
for (int n = 9; n > 0 && s > 0; --n) {
if (s >= n) {
answer += n * tens;
tens *= 10;
s -= n;
}
}
return answer;
}
Just a quick way to on how code works.
First you need to know sum of which digits equal to S. Since each digit is unique, you can assign a bit to them in a binary number like this:
Bit number Digit
0 1
1 2
2 3
...
8 9
So you can check all numbers that are less than 1 << 9 (numbers with 9 bits corresponding 1 to 9) and check if sum of bits if equal to your sum based on their value. So for example if we assume S=17:
384 -> 1 1000 0000 -> bit 8 = digit 9 and bit 7 = digit 8 -> sum of digits = 8+9=17
Now that you know sum if correct, you can just create number based on digits you found.

Count unique subsets of size k with some S [closed]

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.

Given number N eliminate K digits to get maximum possible number

As the title says, the task is:
Given number N eliminate K digits to get maximum possible number. The digits must remain at their positions.
Example: n = 12345, k = 3, max = 45 (first three digits eliminated and digits mustn't be moved to another position).
Any idea how to solve this?
(It's not homework, I am preparing for an algorithm contest and solve problems on online judges.)
1 <= N <= 2^60, 1 <= K <= 20.
Edit: Here is my solution. It's working :)
#include <iostream>
#include <string>
#include <queue>
#include <vector>
#include <iomanip>
#include <algorithm>
#include <cmath>
using namespace std;
int main()
{
string n;
int k;
cin >> n >> k;
int b = n.size() - k - 1;
int c = n.size() - b;
int ind = 0;
vector<char> res;
char max = n.at(0);
for (int i=0; i<n.size() && res.size() < n.size()-k; i++) {
max = n.at(i);
ind = i;
for (int j=i; j<i+c; j++) {
if (n.at(j) > max) {
max = n.at(j);
ind = j;
}
}
b--;
c = n.size() - 1 - ind - b;
res.push_back(max);
i = ind;
}
for (int i=0; i<res.size(); i++)
cout << res.at(i);
cout << endl;
return 0;
}
Brute force should be fast enough for your restrictions: n will have max 19 digits. Generate all positive integers with numDigits(n) bits. If k bits are set, then remove the digits at positions corresponding to the set bits. Compare the result with the global optimum and update if needed.
Complexity: O(2^log n * log n). While this may seem like a lot and the same thing as O(n) asymptotically, it's going to be much faster in practice, because the logarithm in O(2^log n * log n) is a base 10 logarithm, which will give a much smaller value (1 + log base 10 of n gives you the number of digits of n).
You can avoid the log n factor by generating combinations of n taken n - k at a time and building the number made up of the chosen n - k positions as you generate each combination (pass it as a parameter). This basically means you solve the similar problem: given n, pick n - k digits in order such that the resulting number is maximum).
Note: there is a method to solve this that does not involve brute force, but I wanted to show the OP this solution as well, since he asked how it could be brute forced in the comments. For the optimal method, investigate what would happen if we built our number digit by digit from left to right, and, for each digit d, we would remove all currently selected digits that are smaller than it. When can we remove them and when can't we?
In the leftmost k+1 digits, find the largest one (let us say it is located at ith location. In case there are multiple occurrences choose the leftmost one). Keep it. Repeat the algorithm for k_new = k-i+1, newNumber = i+1 to n digits of the original number.
Eg. k=5 and number = 7454982641
First k+1 digits: 745498
Best number is 9 and it is located at location i=5.
new_k=1, new number = 82641
First k+1 digits: 82
Best number is 8 and it is located at i=1.
new_k=1, new number = 2641
First k+1 digits: 26
Best number is 6 and it is located at i=2
new_k=0, new number = 41
Answer: 98641
Complexity is O(n) where n is the size of the input number.
Edit: As iVlad mentioned, in the worst case complexity can be quadratic. You can avoid that by maintaining a heap of size at most k+1 which will increase complexity to O(nlogk).
Following may help:
void removeNumb(std::vector<int>& v, int k)
{
if (k == 0) { return; }
if (k >= v.size()) {
v.clear();
return;
}
for (int i = 0; i != v.size() - 1; )
{
if (v[i] < v[i + 1]) {
v.erase(v.begin() + i);
if (--k == 0) { return; }
i = std::max(i - 1, 0);
} else {
++i;
}
}
v.resize(v.size() - k);
}

Find number of palindromes that are anagrams in C++

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.

different length permutations [duplicate]

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.