i am having problems with my downheap function - c++

I am trying to write a down heap function for my heap but it keeps getting stuck in an infinite loop and I'm not sure why. also, i am not sure how to make it so it doesn't check outside of my last variable which is part of the problem i think
this is where it gets stuck
else if(2*i+1 <= last&& arr[2*i+1]!=0 && 2*i > last)
void heap::downheap()
{
int temp= 0;
int i = 1;
while(i < last)
{
// if(2*i > last|| 2*i+1 >last){
// cout<< "error"<<endl;
//}
if(2*i <= last && 2*i+1 <=last){
if(arr[i] < arr[2*i] && arr[2*i] > arr[2*1+1])
{
cout<< "left";
temp = arr[i];
arr[i] = arr[2 *i];
arr[2*i] = temp;
if(arr[i*2] > arr[i*2+1])
i = i*2;
else
i = i * 2+1;
}
else if(arr[i] < arr[i*2+1] && arr[2*i+1] > arr[2*1])
{
cout<< "right";
temp = arr[i];
arr[i] = arr[2 *i+1];
arr[2*i+1] = temp;
//i++;// = i*2+1;
if(arr[i*2+1] > arr[i*2])
i = i*2+1;
else
i = i * 2;
}
else if(arr[i] > arr[i*2] || arr[i*2+1])
{
if(arr[i*2+1] > arr[i*2])
i = i*2+1;
else
i = i * 2;
}
}
else if(2*i <= last && arr[2*i]!=0 && 2*i+1 > last)
{
temp = arr[i];
arr[i] = arr[2 *i];
arr[2*i] = temp;
//i++;// = i*2;
if(arr[i*2] > arr[i*2+1])
i = i*2;
else
i = i * 2+1;
}
else if(2*i+1 <= last&& arr[2*i+1]!=0 && 2*i > last)
{
temp = arr[i];
arr[i] = arr[2 *i+1];
arr[2*i+1] = temp;
//i++;// = i*2+1;
if(arr[i*2+1] > arr[i*2])
i = i*2+1;
else
i = i * 2;
}
}
}
this is as far as i get
-1 to remove 0 to stop: -1
removed 8
7 1 6 4 3 2 5
-1 to remove 0 to stop: -1
removed 7
6 1 2 4 3 5
-1 to remove 0 to stop: -1

Related

Google kickstart 2021 L shaped plots cannot understand what is wrong here?

So here is the code I wrote for the question(https://codingcompetitions.withgoogle.com/kickstart/round/0000000000436140/000000000068c509#problem). For the sample input I am getting the right answer but it is not clearing test set 1.
I have created the code such that it checks for "1" up down right and left for each element of array and sees whether from that junction an L can be made.
For reference these are the conditions in the question:
"A segment is called "good" if all the cells in the segment contain only 1s.
An "L-shape" is defined as an unordered pair of segments, which has all the following properties:
Each of the segments must be a "good" segment.
The two segments must be perpendicular to each other.
The segments must share one cell that is an endpoint of both segments.
Segments must have length at least 2.
The length of the longer segment is twice the length of the shorter segment."
#include <bits/stdc++.h>
int main()
{
using namespace std;
int t, u;
cin >> t;
for (u = 1; u <= t; u++) {
int i, j, k, l = 0, a[40][40], r, c, right = 0, left = 0, up = 0, down = 0, downc, upc, lc, rc;
cin >> r >> c;
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++) {
cin >> a[i][j];
}
}
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++) {
if (a[i][j] == 1) {
right = 0;
left = 0;
up = 0;
down = 0;
downc = 0;
upc = 0;
lc = 0;
rc = 0;
for (k = i; k < r; k++) {
if (a[k][j] == 0)
break;
else
down++;
}
for (k = i; k >= 0; k--) {
if (a[k][j] == 0)
break;
else
up++;
}
for (k = j; k < c; k++) {
if (a[i][k] == 0)
break;
else
right++;
}
for (k = j; k >= 0; k--) {
if (a[i][k] == 0)
break;
else
left++;
}
if (!(up > 1 && down > 1 && right > 1 && left > 1)) {
downc = down;
upc = up;
rc = right;
lc = left;
if (up >= 2) {
if (right >= 4) {
while ((upc * 2) > right)
upc--;
l = l + upc - 1;
}
upc = up;
if (left >= 4) {
while ((upc * 2) > left)
upc--;
l = l + upc - 1;
}
upc = up;
}
if (down >= 2) {
if (right >= 4) {
while ((downc * 2) > right)
downc--;
l = l + downc - 1;
}
downc = down;
if (left >= 4) {
while ((downc * 2) > left)
downc--;
l = l + downc - 1;
}
downc = down;
}
if (right >= 2) {
if (up >= 4) {
while ((rc * 2) > up)
rc--;
l = l + rc - 1;
}
rc = right;
if (down >= 4) {
while ((rc * 2) > down)
rc--;
l = l + rc - 1;
}
rc = right;
}
if (left >= 2) {
if (up >= 4) {
while ((lc * 2) > up)
lc--;
l = l + lc - 1;
}
lc = left;
if (down >= 4) {
while ((lc * 2) > down)
lc--;
l = l + lc - 1;
}
lc = left;
}
}
}
}
}
cout << "Case #" << u << ": " << l << "\n";
}
}
Ok so I found the issue finally :
There was no need for " if (!(up > 1 && down > 1 && right > 1 && left > 1)) {.....}"
But still this code is too time consuming to run 1000x1000 grid case. Hence it fails test 2.
Edit: It was a mistake on my end. I bounded the array as 40x40. On changing it to a[1000][1000] it ran both tests successfully. Congos to me.

Adding terminal gap scores in C++ code for optimal sequence alignment score

Hello I have been attempting to add a scoring scheme which is 11 for internal gaps, 8 for terminal gaps on the 5 prime end, 7 for gaps on the 3' end, 4 for mismatches, 0 for matches. Currently the code only accounts for internal gap (= 11), mismatches(= 4) and matches (=0) but not for terminal gaps. Im fairly new to coding so I apologise in advance if my code is messy, any guidance is appreciated. I should be getting a score of 275.
The two sequences I used are included in the code.
#include <iostream>
#include <fstream>
#include <bits/stdc++.h>
using namespace std;
void getscore(string x, string y, int pxy, int pgap)
{
int i, j;
int m = x.length();
int n = y.length();
int dp[n+m+1][n+m+1] = {0};
for (i = 0; i <= (n+m); i++)
{
dp[i][0] = i * pgap;
dp[0][i] = i * pgap;
}
for (i = 1; i <= m; i++)
{
for (j = 1; j <= n; j++)
{
if (x[i - 1] == y[j - 1])
{
dp[i][j] = dp[i - 1][j - 1];
}
else
{
dp[i][j] = min({dp[i - 1][j - 1] + pxy ,
dp[i - 1][j] + pgap ,
dp[i][j - 1] + pgap });
}
}
}
int l = n + m;
i = m; j = n;
int xpos = l;
int ypos = l;
int xans[l+1], yans[l+1];
while ( !(i == 0 || j == 0))
{
if (x[i - 1] == y[j - 1])
{
xans[xpos--] = (int)x[i - 1];
yans[ypos--] = (int)y[j - 1];
i--; j--;
}
else if (dp[i - 1][j - 1] + pxy == dp[i][j])
{
xans[xpos--] = (int)x[i - 1];
yans[ypos--] = (int)y[j - 1];
i--; j--;
}
else if (dp[i - 1][j] + pgap == dp[i][j])
{
xans[xpos--] = (int)x[i - 1];
yans[ypos--] = (int)'_';
i--;
}
else if (dp[i][j - 1] + pgap == dp[i][j])
{
xans[xpos--] = (int)'_';
yans[ypos--] = (int)y[j - 1];
j--;
}
}
while (xpos > 0)
{
if (i > 0) xans[xpos--] = (int)x[--i];
else xans[xpos--] = (int)'_';
}
while (ypos > 0)
{
if (j > 0) yans[ypos--] = (int)y[--j];
else yans[ypos--] = (int)'_';
}
int id = 1;
for (i = l; i >= 1; i--)
{
if ((char)yans[i] == '_' && (char)xans[i] == '_')
{
id = i + 1;
break;
}
}
// Printing the final answer
cout << "Optimal score = ";
cout << dp[m][n] << "\n";
cout << "Optimal alignment :\n";
for (i = id; i <= l; i++)
{
cout<<(char)xans[i];
}
cout << "\n";
for (i = id; i <= l; i++)
{
cout << (char)yans[i];
}
return;
}
int main(){
string geneA = "TCTGGTGTCCTAGGCGTAGAGGAACCACACCAATCCATCCCGAACTCTGGTGGTTAAACTCTACTGCGGTGACGATACT ";
string geneB = "TGGTGCGGTCATACCAGCGCTAATGCACCGGATCCCATCAGAACTCCGCAGTTAAGCGCGCTTGGGCCAGAACAGTACTGGGATGGGTGTCC ";
int misMatchPenalty = 4;
int gapPenalty = 11;
int tPenalty=7;
int fPenalty=8;
getscore(geneA, geneB,
misMatchPenalty, gapPenalty);
return 0;
}

Runtime Error signal 11 on simple C++ code

I am getting a runtime error with this code and I have no idea why.
I am creating a grid and then running a BFS over it. The objective here is to read in the rows and columns of the grid, then determine the maximum number of stars you can pass over before reaching the end.
The start is the top left corner and the end is the bottom right corner.
You can only move down and right. Any ideas?
#include <iostream>
#include <queue>
using namespace std;
int main() {
int r, c, stars[1001][1001], grid[1001][1001], ns[1001][1001];
pair<int, int> cr, nx;
char tmp;
queue<pair<int, int> > q;
cin >> r >> c;
for(int i = 0; i < r; i++) {
for(int j = 0; j < c; j++) {
cin >> tmp;
if(tmp == '.') {
grid[i][j] = 1000000000;
ns[i][j] = 0;
stars[i][j] = 0;
}
else if(tmp == '*') {
grid[i][j] = 1000000000;
ns[i][j] = 1;
stars[i][j] = 1;
}
else
grid[i][j] = -1;
}
}
grid[0][0] = 0;
cr.first = 0;
cr.second = 0;
q.push(cr);
while(!q.empty()) {
cr = q.front();
q.pop();
if(cr.first < r - 1 && grid[cr.first + 1][cr.second] != -1 && ns[cr.first][cr.second] + stars[cr.first + 1][cr.second] > ns[cr.first + 1][cr.second]) {
nx.first = cr.first + 1; nx.second = cr.second;
grid[nx.first][nx.second] = grid[cr.first][cr.second] + 1;
ns[nx.first][nx.second] = ns[cr.first][cr.second] + stars[cr.first + 1][cr.second];
q.push(nx);
}
if(cr.second < c - 1 && grid[cr.first][cr.second + 1] != -1 && ns[cr.first][cr.second] + stars[cr.first][cr.second + 1] > ns[cr.first][cr.second + 1]) {
nx.first = cr.first; nx.second = cr.second + 1;
grid[nx.first][nx.second] = grid[cr.first][cr.second] + 1;
ns[nx.first][nx.second] = ns[cr.first][cr.second] + stars[cr.first][cr.second + 1];
q.push(nx);
}
}
if(grid[r - 1][c - 1] == 1000000000)
cout << "Impossible" << endl;
else
cout << ns[r - 1][c - 1] << endl;
}
Sample input :
6 7
.#*..#.
..*#...
#.....#
..###..
..##..*
*#.....
I'm guessing your stack is not big enough for
int stars[1001][1001], grid[1001][1001], ns[1001][1001];
which is 3 * 1001 * 1001 * sizeof(int) bytes. That's ~12MB if the size of int is 4 bytes.
Either increase the stack size with a compiler option, or go with dynamic allocation i.e. std::vector.
To avoid the large stack you should allocate on the heap
Since you seem to have three parallel 2 - dimension arrays you could
maybe create struct that contains all three values for a x,y position.
That would make it easier to maintain:
struct Area
{
int grid;
int ns;
int stars;
};
std::vector<std::array<Area,1001>> dim2(1001);
dim2[x][y].grid = 100001;
...

Algorithm to calculate sum of LUCKY FACTOR in given range

Problem Statement :-
A number is given, N, which is given in binary notation, and it
contains atmost 1000000 bits. You have to calculate the sum of LUCKY
FACTOR in range from 1 to N (decimal notation).
Here, LUCKY FACTOR means, (after converting into binary representation) if
rightmost or leftmost 1's neighbour is either 0 or nothing(for
boundary bit).
EDITED :-
Means if rightmost one's left neighbour is 0, means it count as a
LUCKY FACTOR, simlarly in the left side also
Example,
5 == 101, LUCKY FACTOR = 2.
7 == 111, LUCKY FACTOR = 0.
13 == 1101, LUCKY FACTOR = 1.
16 == 1110, LUCKY FACTOR = 0.
0 == 0, LUCKY FACTOR = 0.
Answer must be in binary form
I am totally stuck, give me a hint.
My code
#include<stdio.h>
#include<string>
#include<string.h>
#include<vector>
//#include<iostream>
using namespace std;
vector<string> pp(10000001);
string add(string a, string b) {
if(b == "") return a;
string answer = "";
int c = 0;
int szeA = a.size() - 1;
int szeB = b.size() - 1;
while(szeA >= 0 || szeB >= 0) {
answer = (char)( ( ( ( (szeA >= 0) ? (a[szeA] - 48) : 0 ) ^ ( (szeB >= 0) ? (b[szeB] - 48) : 0 ) ) ^ (c) ) + 48 ) + answer;
c = ( ( ( (szeA >= 0) ? (a[szeA] - 48) : 0 ) & ( (szeB >= 0) ? (b[szeB] - 48) : 0 ) ) | ( ( (szeA >= 0) ? (a[szeA] - 48) : 0 ) & (c) ) | ( ( (szeB >= 0) ? (b[szeB] - 48) : 0 ) & (c) ) );
szeA--;
szeB--;
}
if(c) answer = '1' + answer;
return answer;
}
string subtract(string a, string b) {
int sze = a.size() - b.size();
while(sze--) b = '0' + b;
sze = a.size();
for(int i = 0; i < sze; i++) {
if(b[i] == '1') b[i] = '0';
else b[i] = '1';
}
if(b[sze-1] == '0') {
b[sze-1] = '1';
}
else {
int i = sze-1;
while(i >= 0 && b[i] == '1') {
b[i] = '0';
i--;
}
if(i >= 0) b[i] = '1';
else b = '1' + b;
}
b = add(a, b);
b.erase(b.begin() + 0);
//b[0] = '0';
while(b[0] == '0') b.erase(b.begin() + 0);
return b;
}
string power(int index) {
if(index < 0) return "";
string answer = "";
while(index--) {
answer = '0' + answer;
}
answer = '1' + answer;
return answer;
}
string convert(long long int val) {
int divisionStore=0;
int modStore=0;
string mainVector = "";
do {
modStore=val%2;
val=val/2;
mainVector = (char)(modStore+48) + mainVector;
}while(val!=0);
return mainVector;
}
string increment(string s) {
int sze = s.size()-1;
if(s[sze] == '0') {
s[sze] = '1';
return s;
}
while(sze >= 0 && s[sze] == '1') {
s[sze] = '0';
sze--;
}
if(sze >= 0) s[sze] = '1';
else s = '1' + s;
return s;
}
main() {
int T;
char s[1000001];
string answer;
scanf("%d", &T);
for(int t = 1; t <= T; t++) {
int num;
answer = "1";
int bitComeEver = 0;
int lastBit = 0;
scanf("%s", s);
int sze = strlen(s);
// I used below block because to avoid TLE.
if(sze > 3300) {
printf( "Case #%d\n", t);
for(int i = 0; i < sze; i++) printf("%c", '1');
printf("\n");
//continue;
}
else {
if(pp[sze-1] != "") answer = pp[sze-1];
else {
pp[sze-1] = power(sze-1);
answer = pp[sze-1];
}
answer = subtract(answer, convert(sze-1));
////////////////////////////
//cout << answer << endl;
for(int i = 1; i < sze; i++) {
if(s[i] == '1') {
if(s[1] == '0') {
num = sze-i-1;
if(num > 0) {
if( pp[num-1] == "") {
pp[num-1] = power(num-1);
}
if(pp[num+1] == "") {
pp[num+1] = power(num+1);
}
answer = add(answer, subtract(pp[num+1], pp[num-1]));
if(lastBit) answer = add(answer, "1");
//else answer = increment(answer);
//cout << "\t\t" << answer << endl;
}
else{
int inc;
if(lastBit) inc = 2; //answer = add(answer, "10");
else inc = 1; //answer = increment(answer);
if(s[i-1] == '0') lastBit = 1;
else lastBit = 0;
if(lastBit) inc += 2;
else inc += 1;
if(inc == 2) answer = add(answer, "10");
else if(inc == 3) answer = add(answer, "11");
else answer = add(answer, "100");
}
}
else {
if(num > 0) {
if(pp[num-1] != "") pp[num-1] = power(num-1);
answer = add(answer, pp[num-1]);
}
else {
int inc = 0;
if(lastBit) inc = 1; //answer = increment(answer);
if(s[i-1] == '0') lastBit = 1;
else lastBit = 0;
if(lastBit) inc += 1;
answer = add(answer, convert(inc));
}
}
if(s[i-1] == '0') lastBit = 1;
else lastBit = 0;
}
}
if(s[sze-1] == '0') {
if(lastBit) {
if(s[1] == '0') {
answer = add(answer, "10");
}
else answer = increment(answer);
}
else if(s[1] == '0'){
answer = increment(answer);
}
}
printf( "Case #%d\n", t);
for(int i = 0; i < sze; i++) printf("%c", answer[i]);
printf("\n");
}
}
return 0;
}
If a number has k bits, then calculate the number of such numbers having a LUCKY FACTOR of 2:
10.............01
Hence in this the 1st two and last two digits are fixed, the remaining k-4 digits can have any value. The number of such numbers = 2^(k-4).
So you can easily calculate the sum of lucky factors of such numbers = lucky_factor x 2^(k-4)
(ofcourse this is assuming k >= 4)
What's more, you do not need to calculate this number since it will be of the form 10000000.
If the number n is 11010010. Then 8 bit numbers less than n shall be of form:
10........ or 1100...... or 1101000_. If you see a pattern, then we have divided the calculation in terms of the number of 1s in the number n
.
I leave the rest for you.

Codechef Q - Why am I getting a "Wrong Answer" error

Question - A Little Elephant from the Zoo of Lviv likes lucky numbers very much. Everybody knows that the lucky numbers are positive integers whose decimal representation contains only the lucky digits 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467 are not.
Let F4(X) be the number of digits 4 in the decimal representation of X, and F7(X) be the number of digits 7 in the decimal representation of X. For example, F4(456) = 1, F4(444) = 3, F7(1) = 0, F7(747) = 2. The Little Elephant wants to know the largest product F4(X) ∙ F7(X), where L ≤ X ≤ R. In other words he wants to know the value
max{F4(X) ∙ F7(X) : L ≤ X ≤ R}.
1 <= L <= R <= 1018
Example:
1) For the range, 1 100 answer will be 1 {47,74}
2) 4199 6000 answer will be 4 {4747, 4477}
I feel my code is correct, but on submitting it's getting the verdict Wrong Answer. Can anybody help me find out exactly what is going wrong?
My algorithm cannot be wrong (it's very straightforward). I've double checked the implementation (it handles all possible cases). It's difficult to believe that it's going wrong for some input.
Here's the C++ code:
#include <cstdio>
#include <cstring>
using namespace std;
char buf1[20],buf2[20];
int *L, *R, *ans, len, ansn;
bool flagL, flagR;
inline int count(int n)
{
int a=0,c=0;
for(;a<len;a++) if(ans[a] == n) c++;
return c;
}
inline int max(int a, int b) { return a>b ? a:b; }
inline int min(int a, int b) { return a<b ? a:b; }
inline void f(int i, int n)
{
int a=0,n4=0,n7=0,t;
for(;a<=i;a++) if(ans[a] == 4) n4++; else if(ans[a] == 7) n7++;
while(n)
{
if(n4 == n7)
{
n4 += n/2;
n7 += (n-n/2);
break;
}
else if(n4 > n7)
{
t = min(n,n4-n7);
n -= t;
n7 += t;
}
else if(n7 > n4)
{
t = min(n,n7-n4);
n -= t;
n4 += t;
}
}
ansn = max(ansn,n4*n7);
}
void solve(int i, bool flagL, bool flagR)
{
while(i<len)
{
if(flagL && !flagR)
{
if(4 > L[i])
{
f(i-1,len-i);
return;
}
if(4 == L[i])
{
ans[i] = 4;
solve(i+1, 1, 0);
ans[i] = 7;
f(i,len-i-1);
return;
}
if(7 > L[i])
{
ans[i] = 7;
f(i,len-i-1);
return;
}
if(7 == L[i])
{
ans[i] = 8;
f(i,len-i-1);
ans[i] = 7;
i++;
continue;
}
// else
ans[i] = 9;
if(ans[i] > L[i])
{
f(i,len-i-1);
return;
}
else
{
i++;
continue;
}
}
if(!flagL && flagR)
{
if(7 < R[i])
{
f(i-1,len-i);
return;
}
if(7 == R[i])
{
ans[i] = 4;
f(i,len-i-1);
ans[i] = 7;
i++;
continue;
}
if(4 < R[i])
{
ans[i] = 4;
f(i,len-i-1);
return;
}
if(4 == R[i])
{
ans[i] = 3;
f(i,len-i-1);
ans[i] = 4;
i++;
continue;
}
// else
ans[i] = 0;
if(ans[i] < R[i])
{
f(i,len-i-1);
return;
}
else
{
i++;
continue;
}
}
if(flagL && flagR)
{
if(R[i] - L[i] == 1)
{
ans[i] = L[i];
solve(i+1,1,0);
ans[i]++;
solve(i+1,0,1);
return;
}
bool four = 4 > L[i] && 4 < R[i];
bool sev = 7 > L[i] && 7 < R[i];
if (four && sev)
{
f(i-1,len-i);
return;
}
else if (four && !sev)
{
ans[i] = 4;
f(i,len-i-1);
}
else if (!four && sev)
{
ans[i] = 7;
f(i,len-i-1);
}
if (L[i] == 4 || L[i] == 7 || R[i] == 4 || R[i] == 7)
{
if(L[i] == R[i]) { ans[i] = L[i]; i++; continue; }
if(L[i] == 4 && R[i] == 7)
{
ans[i] = 4;
solve(i+1,1,0);
ans[i] = 7;
solve(i+1,0,1);
ans[i] = 5;
f(i,len-i-1);
return;
}
if(R[i] - L[i] >= 2)
{
ans[i] = L[i]+1;
f(i,len-i-1);
if(L[i] == 4 || L[i] == 7)
{
ans[i] = L[i];
solve(i+1,1,0);
}
if(R[i] == 4 || R[i] == 7)
{
ans[i] = R[i];
solve(i+1,0,1);
}
return;
}
}
else
{
if (R[i] - L[i] >= 2)
{
ans[i] = L[i]+1;
f(i,len-i-1);
return;
}
ans[i] = L[i];
}
}
i++;
} // end of while
ansn = max(ansn, count(4)*count(7));
}
int main()
{
int a,t; scanf("%d\n",&t);
while(t--) // test cases
{
scanf("%s %s",&buf1,&buf2);
len = strlen(buf2);
L = new int[len];
R = new int[len];
ans = new int[len];
for(a=0;a<len;a++) R[a] = buf2[a]-48;
for(a=0;a<len-strlen(buf1);a++) L[a] = 0;
int b=a;
for(;a<len;a++) L[a] = buf1[a-b]-48;
flagL = flagR = 1; ansn = 0;
solve(0,1,1);
printf("%d\n",ansn);
}
return 0;
}
The algorithm:
Firstly, put the digits of L,R in arrays L[],R[] of length = no. of digits in R. And initialize an array ans[] for keeping track of the answer integer (integer for which F4(ans)*F7(ans) is maximum).
Pad L by 0 on the left, to make it equal to R in length. (so 1,100 becomes 001,100)
This is done in main() itself, before making a call to solve()
The real logic:
Run a loop, for i in range(0,len(R))
For each i, compare L[i] and R[i]
Variables flagL and flagR tell you whether or not, you need to check L and R respectively.
Supposing the L[], R[] is initially:
238 967
First we need to check both of them starting from 0th index (hence solve(0,1,1) or solve(0,true,true) ).
Now 4 and 7 both fall between L[0] and R[0]. So any permutation of {4,7} can be put in the 3 digits, without ans[] going out of range [L,R]. So answer will be 2.
If the range would have been:
238 and 545
Only 4 would fall in between 2 and 5, so we shall put 4 in ans[0], and any permutation of {4,7} can be put in the remaining places. So answer is again 2.
What if the range is:
238 and 410
Neither 4 nor 7 fall in between L[0] and R[0].
But note that R[0] is 4.
So we shall now have 2 choices to put, 4 and L[0]+1 (this is where recursion comes in)
Why L[0]+1 ? Because if we put L[0]+1 in ans[0], ans[0] would fall in between L[0] and R[0] (for this R[0] - L[0] >= 2) and whatever we put in the remaining digits, ans[] would never go out of range. But we also have to check with ans[0] being 4. In the last example, it won't help, but it would if R was >= 477.
So the answer would be 1. (2 if R was >= 477)
Let's discuss another example:
Range: 4500 5700
Because R[0] and L[0] differ by only 1, we will have to check for both, once for ans[i] = L[i], then ans[i] = R[i] (or ans[i]++ )
Now if we check for ans[i] = 4, we won't have to compare ans[i] and R[i] anymore, since ans[0] < R[0], hence ans will always be < R. So we call solve() recursively like this: solve(i+1, true, false)
Next time, when ans[0] = R[0], then we won't have to compare ans with L (since ans > L, whatever we put in the remaining 2 places). Then we call solve() like this: solve(i+1, false, true).
You get the idea of how it's working, and also, if you look at my code, no possible test case is being left out. I don't know why I'm getting a WA.
PS: Andrew pointed out the mistake. The order of conditions was wrong. The if block 4 == L[i] should have come before the if block 7 > L[i]. Now the code works correctly.
if(7 > L[i]) // 7 > 4 ?
{
ans[i] = 7;
f(i,len-i-1);
return;
}
if(4 == L[i]) // how is this ever reachable?
{
ans[i] = 4;
solve(i+1, 1, 0);
ans[i] = 7;
f(i,len-i-1);
return;
}
I think you mean:
- if(7 > L[i])
+ if(7 < L[i])