Getting kth digit in a string concatenating all natural numbers - c++

I have an infinitely long string "12345678910111213141516171819202122232425..." which is a concatentation of every natural numbers in ascending order. I want to find the kth character in the string. However, my program is giving me incorrect output despite the logic being correct. I suspect an implementation bug somewhere
#include <iostream>
int main() {
using std::cin;
using std::cout;
std::ios::sync_with_stdio(0);
cin.tie(0);
int T;
cin >> T;
while (T--) {
int64_t k;
cin >> k;
int64_t aux = 9;
int digit = 1;
while (k > aux * digit) {
k -= aux * digit;
aux *= 10;
digit++;
}
int64_t ans = 1;
for (int i = 0; i < digit - 1; i++) {
ans *= 10;
}
ans += (k - 1) / digit - 1;
k -= (k - 1) / digit * digit;
int64_t helper = 1;
for (int i = 0; i < digit - k; i++) {
helper *= 10;
}
cout << ans / helper % 10 << '\n';
}
return 0;
}
Input:
3
7
19
12
Expected Output:
7
4
1
My output
6
3
1

It's almost correct but it seems that you do not have to minus 1 in ans += (k - 1) / digit - 1, changing it to ans += (k - 1) / digit should work.
Output:
7
4
1

Related

Subarray with given sum

Given an unsorted array A of size N of non-negative integers, find a continuous sub-array which adds to a given number S.
Input:
The first line of input contains an integer T denoting the number of test cases. Then T test cases follow. Each test case consists of two lines. The first line of each test case is N and S, where N is the size of array and S is the sum. The second line of each test case contains N space separated integers denoting the array elements.
Output:
For each testcase, in a new line, print the starting and ending positions(1 indexing) of first such occuring subarray from the left if sum equals to subarray, else print -1.
Constraints:
1 <= T <= 100
1 <= N <= 107
1 <= Ai <= 1010
Example:
Input:
2
5 12
1 2 3 7 5
10 15
1 2 3 4 5 6 7 8 9 10
Output:
2 4
1 5
My Code:
#include <iostream>
using namespace std;
int main() {
int t, n, s, a[1000], result[1000];
cin >> t;
for (int i = 0; i < t; i++) {
result[i * 2] = -1;
cin >> n >> s;
for (int j = 0; j < n; j++) {
cin >> a[j];
}
int flag = 0;
for (int j = 0; j < n; j++) {
if (flag == 0) {
int sum = 0;
for (int k = j; k < n && sum < s; k++) {
sum += a[k];
if (sum == s) {
result[i * 2] = j + 1;
result[(i * 2) + 1] = k + 1;
flag = 1;
break;
}
}
}
}
}
for (int i = 0; i < t * 2; i += 2) {
if (result[i] != -1) {
cout << result[i] << " " << result[i + 1] << endl;
} else {
cout << result[i];
}
}
}
Result:
Wrong Answer. !!!Wrong Answer
Possibly your code doesn't work correctly for multiple test-cases (TCs).
The first test case where your code failed:
Input:
4 225
9 45 10 190
Its Correct output is:
-1
And Your Code's output is:
-1-1-1-138 42
I've just found this:
https://www.youtube.com/watch?v=G0ocgTgW464
However I believe that the time complexity is O(n*log(n)) given the fact that map::find is O(log(n))

why my c++ code to find factorials is not working?

#include <iostream>
using namespace std;
int main() {
int n, t;
cin >> n;
int i;
for(i = 0; i < n; i++){
cin >> t;
int arr[200];
arr[0] = 1;
int j;
for(j = 1; j < 200; j++) arr[j] = 0;
int l = 1, k;
for(j = 1; j <= t; j++){
int rem = 0, flag = 0;
for(k = 0; k < l; k++){
int temp = (arr[k]*j) ;
arr[k] = (temp + rem) % 10;
rem = (temp+rem) / 10;
if(k == l-1 && rem != 0){
arr[l] = rem;
flag = 1;
}
}
if(flag) l++;
}
while(l--){
cout << arr[l];
}
if(i != n-1){
cout << "\n";
}
}
return 0;
}
Question statement:
You are asked to calculate the factorials of some small positive integers.
Input:
An integer n, 1<=n<=100, denoting the number of testcases, followed by n lines, each containing a single integer t, 1<=t<=100.
Output:
For each integer n given at input, display a line with the value of t!
This is working fine for t < 35 but starts giving error for t >= 35.
Also tell me how can I improve my coding style. I am new to coding.
CASE 1
sample input:
2
1
35
actual output:
1
-40427027-3-786144929666651337523200000000
expected output:
1
10333147966386144929666651337523200000000
CASE 2
sample input:
3
5
6
7
actual output:
120
720
5040
expected output:
120
720
5040
PS Sorry!, Initial question changed as I ignored floating point errors while calculating 17! from scientific calculator. Now, code is not working for values greater than 34
Error was in part that rem can be a 3 digit number so diving by 10 doesn't work. Need to take care for rem > 100
That part of your code looks wrong since it cycles only up to length of your number
so it may grow only by one digit when there is flag:
for(k = 0; k < l; k++){
int temp = (arr[k]*j) ;
arr[k] = (temp + rem) % 10;
rem = (temp+rem) / 10;
if(k == l-1 && rem != 0){
arr[l] = rem;
flag = 1;
}
}
if(flag) l++;
It should be something shorter like:
for(k = 0; k < l; k++) {
rem += arr[k] * j;
arr[k] = rem % 10;
rem /= 10;
if(k == l-1 && rem != 0) ++l;
}

Output not correct for my C++ program

So, I have the following problem:
From the file tabl.in a number n will be read (n<=50).
After that a square array with n rows and n columns will be read; all the numbers in the array will be composed by a maximum of 2 digits each.
Shown in the file tabl.out, the modulo between the sum of numbers found on the second diagonal of the array and 10, if the sum is palindrome (true=1, false=0), and the arithmetic mean of elements situated below of the main diagonal.
Will be writing functions for:
reading the array
calculation of the operation sum of secondary diagonal%10
checking if the previous result it is palindrome
calculation of the arithmetic mean below main diagonal
Example:
tabl.in:
4
5 8 2 12
1 0 3 16
1 2 1 11
5 7 2 19
tabl.out:
2 1 3
where
(12+3+2+5)%10 = 22%10 = 2
22 is palindrome = 1
1+2+2+1+7+5 = 18, 18/6=3
My code so far is:
#include <fstream>
using namespace std;
ifstream fin("tabl.in");
ofstream fout("tabl.out");
void readn(int Arr[][51], int n) {
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
fin >> Arr[i][j];
}
int sumsec(int Arr[][51], int n) {
int s = 0;
float r;
for (int i = 1; i <= n; i++)
s = s + Arr[i][n - i + 1];
r = s % 10;
return r;
}
void pald(int Arr[][51], int n) {
int s = 0, pal = 0;
for (int i = 1; i < n; i++)
s = s + Arr[i][n - i + 1];
while (s != 0) {
pal = pal * 10 + s % 10;
s = s / 10;
}
if (pal == s)
fout << "1 ";
else
fout << "0 ";
}
int ambmd(int Arr[][51], int n) {
int s = 0, k;
float ame;
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= i - 1; j++) {
s = s + Arr[i][j];
k++;
}
}
ame = s / k;
return ame;
}
int main() {
int Arr[51][51], n;
float r, ame;
fin >> n;
readn(Arr, n);
r = sumsec(Arr, n);
fout << r << " ";
pald(Arr, n);
ame = ambmd(Arr, n);
fout << ame;
}
But I have an issue with the palindrome() function: my output file will have 2 0 3 written to it for the given array from the example, instead of 2 1 3. What am I doing wrong?
Your pald function would work, if you compute s the same way as you do in sumsec and if s would still contain the sum, after you compute pal.
In your case, while (s != 0) {...}, followed by if (pal == s) {...} could be re-written as if (pal == 0), which is clearly not the intended solution. Just save your sum before computing pal, then compare with the saved sum.
Also, change your loop condition for computing s to for (int i = 1; i <= n; i++).
int s = 0, pal = 0, sum = 0;
for (int i = 1; i <= n; i++)
s = s + Arr[i][n - i + 1];
sum = s;
while (s != 0) {
pal = pal * 10 + s % 10;
s = s / 10;
}
if (pal == sum)
fout << "1 ";
else
fout << "0 ";
You should also consider the various comments for code improvements, like not re-computing the sum in the pald function.

C++ Sub sequence Exercise

I was assigned a "project" where I should create a C++ program to find the largest possible sum of two sub sequences. The user inputs N (array length), K (length of each sub sequence) and N numbers representing the array. The two sub sequences can touch but can't override each other e.g. 1 5 20 20 20 15 10 1 1 1 should output 90 ((5+20+20)+(20+15_10)) and not 115 ((20+20+20)+(20+20+15)).
My code until now is:
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int N, K, MaxN;
cin >> N;
cin >> K;
int Pi[N];
MaxN = N - K + 1;
int Word[MaxN];
int MaxSum;
for(int nn=0; nn<N; nn++) {
cin >> Pi[nn];
}
for(int y=0;y<MaxN;y++) {
Word[y] = 0;
}
for(int j=0; j<MaxN; j++) {
for(int l=0; l<K; l++) {
Word[j] = Word[j] + Pi[j+l];
}
}
sort(Word, Word + MaxN);
MaxSum = Word[MaxN-2] + Word[MaxN-1];
cout << MaxSum;
return 0;
}
Which is correct only in the case where the 2 sub sequences don't interfere with each other e.g. in an array such as 2 4 15 12 10 1 1 20 4 10 which outputs 71.
Thank you all in advance.
This is solution:
precalculate prefixes and suffixes
iterate end of the first subarray
iterate begin of the second subarray, but start from the end of first sub. ar. + 1
we have sum of numbers on interval from 0 to *end* = prefix[end], but we are interested only in interval [end - k, k], so simply subtract prefix[end] - prefix[end - k - 1]
[0 .. end-k-1, end-k .. end]
The same approach for the second subarray: sum2 = suffix[begin] - suffix[begin + i + 1]
then compare with the previous answer
So we just brute-force all possible sub-arrays which not intersect and find the max their sum
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int N,K,MaxN;
cin >> N;
cin >> K;
int Pi[N];
MaxN=N-K+1;
int Word[MaxN];
int MaxSum;
for(int nn=0;nn<N;nn++){
cin >> Pi[nn];
}
int prefix[N];
int sufix[N];
for (int i = 0; i < N; i++) {
prefix[i] = sufix[i] = 0;
}
for (int i = 0; i < N; i++) {
if (i == 0)
prefix[i] = Pi[i];
else
prefix[i] = Pi[i] + prefix[i - 1];
}
for (int i = N - 1; i >= 0; i--) {
if (i == N - 1)
sufix[i] = Pi[i];
else
sufix[i] = Pi[i] + sufix[i + 1];
}
int ans = 0;
for (int i = K - 1; i < MaxN; i++) {
for (int j = i + 1; j < MaxN; j++) {
int x = prefix[i] - (i - K >= 0 ? prefix[i - K] : 0);
int y = sufix[j] - (j + K < N ? sufix[j + K] : 0);
ans = max(ans, x + y);
}
}
cout << ans;
return 0;
}

Harmonic progression sum c++ openMP

I'm trying to make a parallel version of "Harmonic Progression Sum" problem using opemMP.
But the output are differents each other depending on the inputs. (Parallel and Sequential)
Program:
#include "stdafx.h"
#include <iostream>
#include <sstream>
#include <omp.h>
#include <time.h>
#define d 10 //Numbers of Digits (Example: 5 => 0,xxxxx)
#define n 1000 //Value of N (Example: 5 => 1/1 + 1/2 + 1/3 + 1/4 + 1/5)
using namespace std;
void HPSSeguencial(char* output) {
long unsigned int digits[d + 11];
for (int digit = 0; digit < d + 11; ++digit)
digits[digit] = 0;
for (int i = 1; i <= n; ++i) {
long unsigned int remainder = 1;
for (long unsigned int digit = 0; digit < d + 11 && remainder; ++digit) {
long unsigned int div = remainder / i;
long unsigned int mod = remainder % i;
digits[digit] += div;
remainder = mod * 10;
}
}
for (int i = d + 11 - 1; i > 0; --i) {
digits[i - 1] += digits[i] / 10;
digits[i] %= 10;
}
if (digits[d + 1] >= 5) {
++digits[d];
}
for (int i = d; i > 0; --i) {
digits[i - 1] += digits[i] / 10;
digits[i] %= 10;
}
stringstream stringstreamA;
stringstreamA << digits[0] << ",";
for (int i = 1; i <= d; ++i) {
stringstreamA << digits[i];
}
string stringA = stringstreamA.str();
stringA.copy(output, stringA.size());
}
void HPSParallel(char* output) {
long unsigned int digits[d + 11];
for (int digit = 0; digit < d + 11; ++digit)
digits[digit] = 0;
int i;
long unsigned int digit;
long unsigned int remainder;
#pragma omp parallel for private(i, remainder, digit)
for (i = 1; i <= n; ++i) {
remainder = 1;
for (digit = 0; digit < d + 11 && remainder; ++digit) {
long unsigned int div = remainder / i;
long unsigned int mod = remainder % i;
digits[digit] += div;
remainder = mod * 10;
}
}
for (int i = d + 11 - 1; i > 0; --i) {
digits[i - 1] += digits[i] / 10;
digits[i] %= 10;
}
if (digits[d + 1] >= 5) {
++digits[d];
}
for (int i = d; i > 0; --i) {
digits[i - 1] += digits[i] / 10;
digits[i] %= 10;
}
stringstream stringstreamA;
stringstreamA << digits[0] << ",";
for (int i = 1; i <= d; ++i) {
stringstreamA << digits[i];
}
string stringA = stringstreamA.str();
stringA.copy(output, stringA.size());
}
int main() {
//Sequential Method
cout << "Sequential Method: " << endl;
char outputSeguencial[d + 10];
HPSSeguencial(outputSeguencial);
cout << outputSeguencial << endl;
//Cleaning vector
string stringA = "";
stringA.copy(outputSeguencial, stringA.size());
//Parallel Method
cout << "Parallel Method: " << endl;
char outputParallel[d + 10];
HPSParallel(outputParallel);
cout << outputParallel << endl;
system("PAUSE");
return 0;
}
Examples:
Input:
#define d 10
#define n 1000
Output:
Sequential Method:
7,4854708606╠╠╠╠╠╠╠╠╠╠╠╠
Parallel Method:
6,6631705861╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ÇJ^
Input:
#define d 12
#define n 7
Output:
Sequential Method:
2,592857142857╠╠╠╠╠╠╠╠╠╠╠╠╠╠ÀÂ♂ü─¨#
Parallel Method:
2,592857142857╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ÇJJ
Regards
Pastecode
http://pastecode.org/index.php/view/62768285
Your threads step on each other's toes when updating the digits array. Hence some additions are lost, and you get bogus results (different results in different runs, almost certainly).
You must synchronise the writes to digits, e.g. with an atomic (or critical) section:
// ... <snip>
#pragma omp parallel for private(i, remainder, digit)
for (i = 1; i <= n; ++i) {
remainder = 1;
for (digit = 0; digit < d + 11 && remainder; ++digit) {
long unsigned int div = remainder / i;
long unsigned int mod = remainder % i;
#pragma omp atomic // <- HERE, could also be #pragma omp critical
digits[digit] += div;
remainder = mod * 10;
}
}
// <snip> ...
so that only one thread at a time can update the array. For a task like this, that would probably nullify any gains of splitting the task in several threads, though.
As Daniel Fischer pointed out, you have a write conflict, but you can avoid it more elegantly than with an omp critical section, e.g. by giving each thread it's own copy of digits and aggregating them all at the end of the loop.