Finding perimeter of a recursively modified square - c++

I have a square of side length 1 . Now, after each second, each square of side L will break into four squares each of side L/2.
I need the compute the total perimeter of the resulting figure, where total perimeter is defined as the sum of lengths of all line segments in the resulting figure. For example, the total perimeter of the image on the left is 4L while that on the right is 6L - 4L from the regular square edges and 2L from the internal line segments.
My code:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define mod 1000000007
int main() {
int s;
cin>>s;
long long int ans=4;
for(int i=1;i<=s;i++)
ans+=1<<i;
ans=ans%mod;
cout<<ans<<endl;
return 0;
}
Since the final answer might not fit in a 64-bit signed integer, I am required to compute the answer modulo 1000000007.
For example, after 0 seconds, the length is 4.
After 1 second, the length is 6.
I am not getting the correct output. PLease help

Solve it recursively - let P(L, n) be the "perimeter" of the figure obtained after n iterations, starting with an LxL square. So, P(L, n+1) = 4*P(L/2,n) - 2*L. Also, since the perimeter is linear, P(L/2, n) = P(L, n)/2, giving you P(L,n) = 2*P(L,n-1) - 2*L. Substitute L=1 and run your loop.
int s;
cin>>s;
long long int ans=4;
for(int i=1;i<=s;i++)
{
ans = 2*(ans-1);
ans=ans%mod;
}

The perimeter after s seconds will be : 4+2(2^s-1)
So,
int main()
{
int s;
cout << "Enter Time: ";
cin >> s;
cout << "Perimeter = " << (4 + 2 * (pow( 2, s ) - 1));
}

You have an undivided square. When you split the square into 4 equal squares, you are essentially adding half of the initial perimeter. The outer walls of the original square are included as is in the new perimeter, and add to that the length of the 2 lines drawn inside it, the length of each of which is equal to the side of the square.
noOfsqaures = 1;
oldSide = 1; //one sqaure of side 1
oldPerimeter = 4*oldSide;
loop for the number of seconds
newPerimeter = oldPerimeter + 2*oldSide*noOfSquares
oldSide = oldSide/2; //for the next iteration
oldPermiter = newPermeter //for the next iteration
noOfSquares = noOfSquares*4;

o/p: 4(initial value) +
2 + 4 + 8 + 16 + 32 + ...
I think it would help you for coding. If you need I will give you code
for(int i=1;i<=s;i++)
{
ans+=1<<i;
}

Related

Biggest valued, 'H' shaped area in matrix?

I got the task where I must find the H shaped region which has the biggest sum of numbers in it. Under 'H' shaped region, tha task meant this, consisting of 7 elements and never changing:
x x
xxx
x x
The matrix's size must be 33 or bigger than that, and I don't have to work with rotated 'H' shape. However, it can move upwards and downwards if the matrix is that big (for example a 46 matrix).
I thought of first counting a "maximum" value, starting from the [0][0] element. However, I can't figure out how to move this region-counting along. Could you help me out, please?
Here's my code so far:
#include<iostream>
int main(){
int n = 3;
int m = 4;
int mtx[n][m] = {
1,1,1,3,
1,1,1,3,
1,1,1,3
};
//counting the maximum H value
int max = 0;
for(int i = 0; i < n; i++){
max += mtx[i][0];
}
for(int i = 0; i < n; i++){
max += mtx[i][2];
}
max += mtx[1][1];
int counter = 0;
int j = 0;
int k = 0;
//finding if there is bigger
while(counter >max){
//questioned area, not sure what to do here
if(counter < max){
max = counter;
}
}
return 0;
}
As mentioned in a comment, knowing the single maximum element in the matrix does not help to find the maximum H shape. A concrete counter example:
0 1 0 5
9 1 1 5
0 1 0 5
Maximum element is 9 but maximum sum H shape is
1 0 5
1 1 5
1 0 5
You would need to add more information to know whether the maximum element is part of the maximum H: Only if max_element + 6*min_element > 7*second_smallest_element you can be sure that max_element is part of the biggest sum H. This condition could be refined, but it cannot be made such that the biggest element is always part of the biggest sum H, because thats not true in general (see counter example above).
As suggested in another comment, you should write a function that given coordinates of the upper left corner calculates the sum of elements in the H shape:
#include <iostream>
#include <array>
int H_sum(const std::array<std::array<int,4>,3>& matrix, int x0,int y0){
// A E
// BDF
// C G
int sum = matrix[x0][y0]; // A
sum += matrix[x0+1][y0]; // B
sum += matrix[x0+2][y0]; // C
sum += matrix[x0+1][y0+1]; // D
sum += matrix[x0][y0+2]; // E
sum += matrix[x0+1][y0+2]; // F
sum += matrix[x0+2][y0+2]; // G
return sum;
}
int main() {
std::array<std::array<int,4>,3> mtx{
1,1,1,3,
1,1,1,3,
1,1,1,3
};
for (const auto& row : mtx){
for (const auto& e : row){
std::cout << e;
}
std::cout << "\n";
}
std::cout << H_sum(mtx,0,0);
}
This is of course only something to get you started. Next you have to carefully consider what are the maximum indices you can pass to H_sum without going out-of-bounds. Then write a nested loop to scan all positions of the H and remember the maximum value encountered.
Last but not least, what I described so far is a brute force approach. You calculate sum for all possible H shapes, remember the maximum, and are done. Maybe there is a clever trick to avoid adding all elements multiple times (for example in a larger matrix, the right leg of one H is the left leg of a different H). Though before applying such tricks and trying to be clever I strongly suggest to write something that is perhaps slow but correct, easy to read and verify.

Binary search given slightly inaccurate results

The problem I am trying to solve is the following: I get N rectangular paper strips with 1cm width and length C. I need to cut the strips at a height where the sum of the areas of the cut strip is equal to A. You can see an example bellow for which N = 5, the strips are of length, 5,3,6,2 and 3 cm and A = 3cm where the cut is made at 4cm.
Note that I'm looking here for the red area.
The input is given as follows. The first line in each case begins with two integers N (1 ≤ N ≤ 10^5) and A (1 ≤ A ≤ 10^9) representing respectively the number of strips and the expected resulting area. The next line contains N integers, representing the length C_i (1 <= C_i <= 10^4) of each strip.
The input ends with A = C = 0, which should not be processed.
For each test case, output a single line, the height H of the cut that must be done so that the sum of the area of the cut strips is equal to A cm². Print the answer with 4 decimal places. Output ":D" if no cutting is required, or "-.-" if it’s impossible.
This problem can be found here
My idea for solving this problem was to use a binary search where I pick a height in the middle of the strips and make it larger or smaller depending on whether my cut was too high or too low. My implementation of the problem is given bellow:
#include <iostream>
#include <vector>
#include <iomanip>
#include <algorithm>
using namespace std;
int main(){
vector<int> v; // Vector that holds paper heights
int n; // Number of papers
double h, // Height of the cut
sum, // Area sum
min_n, // Minimum height for cut to happen
max_n, // Maximum height for cut to happen
a; // Desired final area
// Set desired output
cout << fixed << setprecision(4);
/* Get number of papers and desired area,
terminates if N = A = 0
*/
while(cin >> n >> a && (n||a)){
v.resize(n); // Resize vector to fit all papers
// Get all paper sizes
for(int i=0;i<n;i++){
cin >> v[i];
}
/* Sort the vector in decreasing order to
simplify the search
*/
sort(v.begin(),v.end(),greater<int>());
max_n = v[0]; // Largest possible cut is at the height of the largest paper
min_n = 0; // Smallest possible cut is at the base with height 0
// Iterate until answer is found
while(true){
// Initialize cut height as the average of smallest and largest cut sizes
h = (min_n + max_n)/2;
/* The area sum is equal to the sum of the areas of each cut, which is
given by the height of the paper minus the cut height. If the cut is
higher than the paper, the cut has area 0.
*/
sum = 0;
// Using mascoj sugenstion, a few changes were added
int s; // Temporary variable to hold number of time h is subtracted
for(int i=0; i<n;i++){
if(v[i] <= h) break; // From here onward cut area is 0 and there is no point adding
sum += v[i]; // Removed the subtraction inside of the for loop
s++; // Count how many paper strips were used
}
sum -= h*s // Subtracts the area cut from the s paper strips
// If the error is smaller than the significant value, cut height is printed
if(std::abs(sum-a) < 1e-5){
// If no cut is needed print :D else print cut height
(h < 1e-4 ? cout << ":D" << endl : cout << h << endl);
break;
}
// If max_n is "equal" to min_n and no answer was found, there is no answer
else if(max_n - min_n < 1e-7){
cout << "-.-" << endl;
break;
}
// Reduces search interval
sum < a ? max_n = h : min_n = h;
}
}
return 0;
}
The problem is, after submitting my answer I keep getting a 10% error. The website has a tool for comparing the output of you program with the expected output so I ran a test file with over 1000 randomly generated test cases and when I compared both I got a rounding error on the 4th decimal case, unfortunately, I don't have the file nor the script to generate test cases for me anymore. I tried changing the acceptable error to a smaller one but that didn't work. I can't seem to find the error, does any of you have an idea of what is happening?
ps: Although the problem doesn't say on the description, you can get cuts with fractions as heights
Might be your problem, maybe not: This line is exacerbating floating point error: sum += v[i]-h;
Floating points are only so accurate and compounding this error over a larger summation adds up. I would try using multiplication on h and subtracting that from the total sum of applicable lengths. Should be well within the range of the double precision format so I wouldn't worry about overrunning the format.
Not sure to understand your algorithm but I think that can be done a lot simpler using a map instead a vector.
In the following example the map mp memorize how much (the value) strips are of a given lenght (the key).
An advantage of the map is ordered.
Next you can see how much you have to save (not to cat) and calculate the level of the cut starting from zero, adding 1 when appropriate and adding a fraction when neccessary.
Hope the following example can help
#include <map>
#include <iomanip>
#include <iostream>
int main()
{
int n;
int n2;
int v;
int cut;
int a;
std::map<int, std::size_t> mp;
long long int sum;
long long int ts;
std::cout << std::fixed << std::setprecision(4);
while( (std::cin >> n >> a) && ( n || a ) )
{
mp.clear();
n2 = 0;
sum = 0LL;
for ( auto i = 0 ; i < n ; ++i )
{
std::cin >> v;
if ( v > 0 )
{
sum += v;
++mp[v];
++n2;
}
}
// mp is a map, so the values are ordered
// ts is "to save"; sum of lenghts minus a
ts = sum - a;
// cut level
cut = 0;
// while we can add a full cm to the cut level
while ( (ts > 0LL) && (n2 > 0) && (ts >= n2) )
{
++cut;
ts -= n2;
if ( cut >= mp.cbegin()->first )
{
n2 -= mp.cbegin()->second;
mp.erase(mp.cbegin());
}
}
if ( (ts == 0LL) && (cut == 0) )
std::cout << ":D" << std::endl; // no cut required (?)
else if ( n2 == 0 )
std::cout << "-.-" << std::endl; // impossible (?)
else
std::cout << (cut + double(ts) / n2) << std::endl;
}
}
p.s.: observe that a is defined as an integer in the page that you link.

C++ program to calculate e^x

I know there are many examples of this problem but I tried to write a different one myself.
This is using the Taylor series e^x = 1 + x/1! + x^2/2! + x^3/3! + ......
My code compiles and runs but it wont output the correct answer for some imputes and I'm not sure why. is this even usable code or should i scrap it?
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
double final,power,end_n = 1.0,e=1.0,x=2.0, n;
cout<< "n: ";
// usually enter 5 for test
cin>> n;
while (n>1){
power = pow(x,n);
end_n = end_n*n;
e= (power/end_n)+e;
n--;
}
final =e+x;
cout<< final;
return 0;
}
I honestly have no idea what your reasoning is, at all. The code for that particular expansion is trivially simple:
double x;
cin >> x;
double oldres, res=1, top=1, bottom=1;
int iter=1;
do {
oldres=res; // to calculate the difference between iterations
++iter; // next iteration
top*=x; // multiply by one x for each iteration
bottom*=(iter-1); // multiply by the iteration number for each iteration
res+=top/bottom; // and add the fraction to the result
} while(fabs(res-oldres)>.1); // while the difference is still large
cout << res; // done, show the result
To be very clear about something that others are hinting at: if your loop counted up from 1 to n then end_n would equal n! at each step. But counting down, it doesn't. Look at the examples from 1 to 5:
Forwards
n | n!
1 | 1
2 | 2
3 | 6
4 | 24
5 | 120
Backwards
n | end_n
5 | 5
4 | 20
3 | 60
2 | 120
1 | 120
Since absolutely none of your denominators are right, it's a surprise if your code is only wrong for some inputs — in fact it's probably only correct for x=0.
Finally, I hope that this is just an exercise for learning. If you really need the value of e^x you should use exp(x).
I think you are close. Maybe you want something more like this:
#include <iostream>
#include <cmath>
using namespace std;
double factorial(long n)
{
double result = n;
while(--n) result*=n;
}
int main()
{
long n, power;
double final, e=1.0, x=2.0;
cout<< "n: ";
// usually enter 5 for test
cin>> n;
while (n>1)
{
power = pow((double)x, (double)n);
end_n = factorial(n);
e = (power/end_n)+e;
n--;
}
final = e+x;
cout<< final;
return 0;
}
You could actually employ a Horner-like scheme that uses the counting down in an essential manner
1 + x/1! + x^2/2! + x^3/3! + … + x^n/n! = (((((x/n+1)*x/(n-1)+1)*x/(n-2)+…)*x/1+1
e = 1.0;
while (n>0){
e = e*x/n + 1;
n--;
}
Compare the approximations of e^x and 1/(e^-x) for positive x for exactness.
Explore (e^(x/4))^4 for better exactness.

Tracking where a user has landed in a board game

The idea of the program is that it simulates a game board with a user-inputted number of sides, and cells per side. The program then needs to simulate the user rolling two six-sided dice continuously until the starting tile is landed on or passed.
The problem I'm having is with a required function that records the spot the user landed on the most, per side of the game board (like a Monopoly board has 4 sides). For example, a Monopoly board with 4 sides, 10 cells on each side.
Side 1 has Cells 1 - 10
Side 2 has Cells 11 - 20
Side 3 has Cells 21 - 30
Side 4 has Cells 31 - 40
I'd need to report which cells I landed on the most for each of those four sides, or however many sides the gameboard has.
I have no idea how to start this function. I don't want the code to be written out for me, just a nudge in the right direction. As for the rest of the program, this is what I have:
#include <iostream>
#include <cmath>
#include <ctime>
#include <cstdlib>
using namespace std;
int rollNDice(int nDice, int nSides) {
int diceSum = 0;
for (int i = 0; i < nDice; i++) {
int randnum = 1 + (rand() % (nSides - 1 + 1));
diceSum = diceSum + randnum;
}
return diceSum;
}
int mostLandings(const int boardVector, int startInterval, int endInterval) {
}
int main() {
srand(333);
int boardSides = 0;
int boardSpotsPerSide = 0;
int numberOfSims = 0;
int diceMove = 0;
int startInterval = 0;
int endInterval = 0;
const int boardVector = 0;
cout << "How many sides of the board are there? ";
cin >> boardSides;
cout << "How many spots on each side? ";
cin >> boardSpotsPerSide;
cout << "How many simulations? ";
cin >> numberOfSims;
for (int i = 0; i < boardSides;) {
const int boardVector = boardSides * boardSpotsPerSide;
int spotsPerInterval = boardVector / boardSides;
startInterval = spotsPerInterval / spotsPerInterval + (10 * i);
endInterval = spotsPerInterval * (i + 1);
mostLandings(boardVector, startInterval, endInterval)
i++;
}
}
One possible approach would be to start by calculating the total amount of squares on the board. The amount of squares q can be given by
q = 2s + (s-1)(n-1) = sn + s- n + 1
where s is the amount of squares on each side and n is the amount of sides. Next, store each roll value and loop over the sum of the roll value and the player's previous position, and store those values in a separate array. Take each element in that array modulo q and store in a separate array. This array should be the index of each square landed on after each subsequent turn, which you can manipulate and read from as you like.

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.