Fastest way to calculate all the even squares from 1 to n? - c

I did this in c :
#include<stdio.h>
int main (void)
{
int n,i;
scanf("%d", &n);
for(i=2;i<=n;i=i+2)
{
if((i*i)%2==0 && (i*i)<= n)
printf("%d \n",(i*i));
}
return 0;
}
What would be a better/faster approach to tackle this problem?

Let me illustrate not only a fast solution, but also how to derive it. Start with a fast way of listing all squares and work from there (pseudocode):
max = n*n
i = 1
d = 3
while i < max:
print i
i += d
d += 2
So, starting from 4 and listing only even squares:
max = n*n
i = 4
d = 5
while i < max:
print i
i += d
d += 2
i += d
d += 2
Now we can shorten that mess on the end of the while loop:
max = n*n
i = 4
d = 5
while i < max:
print i
i += 2 + 2*d
d += 4
Note that we are constantly using 2*d, so it's better to just keep calculating that:
max = n*n
i = 4
d = 10
while i < max:
print i
i += 2 + d
d += 8
Now note that we are constantly adding 2 + d, so we can do better by incorporating this into d:
max = n*n
i = 4
d = 12
while i < max:
print i
i += d
d += 8
Blazing fast. It only takes two additions to calculate each square.

I like your solution. The only suggestions I would make would be:
Put the (i*i)<=n as the middle clause of your for loop, then it's checked earlier and you break out of the loop sooner.
You don't need to check and see if (i*i)%2==0, since 'i' is always positive and a positive squared is always positive.
With those two changes in mind you can get rid of the if statement in your for loop and just print.

Square of even is even. So, you really do not need to check it again. Following is the code, I would suggest:
for (i = 2; i*i <= n; i+=2)
printf ("%d\t", i*i);

The largest value for i in your loop should be the floor of the square root of n.
The reason is that the square of any i (integer) larger than this will be greater than n. So, if you make this change, you don't need to check that i*i <= n.
Also, as others have pointed out, there is no point in checking that i*i is even since the square of all even numbers is even.
And you are right in ignoring odd i since for any odd i, i*i is odd.
Your code with the aforementioned changes follows:
#include "stdio.h"
#include "math.h"
int main ()
{
int n,i;
scanf("%d", &n);
for( i = 2; i <= (int)floor(sqrt(n)); i = i+2 ) {
printf("%d \n",(i*i));
}
return 0;
}

Related

How can i get the Big O Notations in this while loop?

The computational cost will only consider how many times c = c+1; is executed.
I want to represent the Big O notation to use n.
count = 0; index = 0; c = 0;
while (index <= n) {
count = count + 1;
index = index + count;
c = c + 1;
}
I think if the "iteration of count" is k and "iteration of index" is n, then k(k+1)/2 = n.
So, I think O(root(n)) is the answer.
Is that right solution about this question?
Is that right solution about this question?
This is easy to test. The value of c when your while loop has finished will be the number of times the loop has run (and, thus, the number of times the c = c + 1; statement is executed). So, let us examine the values of c, for various n, and see how they differ from the posited O(√n) complexity:
#include <stdio.h>
#include <math.h>
int main()
{
printf(" c root(n) ratio\n"); // rubric
for (int i = 1; i < 10; ++i) {
int n = 10000000 * i;
int count = 0;
int index = 0;
int c = 0;
while (index < n) {
count = count + 1;
index = index + count;
c = c + 1;
}
double d = sqrt(n);
printf("%5d %8.3lf %8.5lf\n", c, d, c / d);
}
return 0;
}
Output:
c root(n) ratio
4472 3162.278 1.41417
6325 4472.136 1.41431
7746 5477.226 1.41422
8944 6324.555 1.41417
10000 7071.068 1.41421
10954 7745.967 1.41416
11832 8366.600 1.41419
12649 8944.272 1.41420
13416 9486.833 1.41417
We can see that, even though there are some 'rounding' errors, the last column appears reasonably constant (and, as it happens, an approximation to √2, which will generally improve as n becomes larger) – thus, as we ignore constant coefficients in Big-O notation, the complexity is, as you predicted, O(√n).
Let's first see how index changes for each loop iteration:
index = 0 + 1 = 1
index = 0 + 1 + 2 = 3
index = 0 + 1 + 2 + 3 = 6
...
index = 0 + 1 + ... + i-1 + i = O(i^2)
Then we need to figure out how many times the loop runs, which is equivalent of isolating i in the equation:
i^2 = n =>
i = sqrt(n)
So your algorithm runs in O(sqrt(n)) which also can be written as O(n^0.5).

Calculate the maximal even cost subarray

I am new to Algorithms and Competitive Programming. I am learning about Dynamic programming and I have a problem as below:
Given an array with n numbers. Define a sub-array is a[i, j] = {a[i], a[i + 1], ..., a[j]}, in other words, elements must be contiguous.
The problem is the find the maximum weight of a sub-array such that
that weight is an even number.
The input is 2 <= n <= 1000000; -100 <= a[i] <= 100
Sample test:
5
-2 1 -4 4 9
Output: 10
For this problem, I can do brute force but with a large value of n, I can not do it with the time limit is 1 second. Therefore, I want to change it to Dynamic programming.
I have an idea but I do not know if it works. I think I can divide this problem into two sub-problems. For each element/number, I consider if it is odd/even and then find the largest sum with its corresponding property (odd + odd or even + even to get a even sum). However, that is just what I think and I really need your help.
Here is C++ algorithm with O(n) time complexity:
const int Inf = 1e9;
int main() {
int n = 5;
vector<int> inputArray = {-2, 1, -4, 4, 9};
int minEvenPrefixSum = 0, minOddPrefixSum = Inf;
bool isOddPrefixSumFound = false;
int prefixSum = 0, answer = -Inf;
for(int i = 0; i < n; ++i) {
prefixSum += inputArray[i];
if(abs(prefixSum) % 2 == 0) {
answer = max(answer, prefixSum - minEvenPrefixSum);
minEvenPrefixSum = min(minEvenPrefixSum, prefixSum);
} else {
if(isOddPrefixSumFound) {
answer = max(answer, prefixSum - minOddPrefixSum);
}
isOddPrefixSumFound = true;
minOddPrefixSum = min(minOddPrefixSum, prefixSum);
}
}
if(answer == -Inf) {
cout << "There is no subarray with even sum";
} else {
cout << answer;
}
}
Explanation:
As #nico-schertler mentioned in commentary this task is very similar with more basic problem of the maximum-sum contiguous sub array. How to solve basic task with O(n) time complexity you can read here.
Now let's store not just one value of the minimum prefix sum, but two. One is for minimum even prefix sum, and the other is for minimum odd prefix sum. As a result, when we process the next number, we look at what the value of the prefix sum becomes. If it is even, we try to update the answer using the minimum even value of the prefix sum, in the other case using the minimum odd value of the prefix sum.

"Hashing" Algorithm Implementation

I am given an input consisting of 2 parts, the first line consists of 2 numbers denoting the size of a matrix, N and M, followed by the matrix itself, A. The maximum size of the matrix is 1 <= N, M <= 100, and each of the elements of the matrix is 0 <= A[i][j] <= pow(10, 9). The "hash" is calculated by adding the elements in each column, and multiplying all the sums, modulo 1000000007 (pow(10, 9) + 7).
My code is as follows:
#include <stdio.h>
int main() {
int rows, cols;
scanf("%d %d", &rows, &cols); getchar();
unsigned long long int data[rows][cols];
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
scanf("%llu", &data[row][col]);
}
getchar();
}
unsigned long long int coltot[cols];
for(int i=0;i<cols;i++){coltot[i]=0;}
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
coltot[col] += data[row][col];
}
}
unsigned long long int colmult, colmulttemp = (coltot[0] % 1000000007);
for (int i = 1; i < cols; i++) {
colmulttemp *= coltot[i];
colmulttemp %= 1000000007;
}
colmult = colmulttemp;
printf("%llu\n", colmult);
return 0;
}
However, upon submission, the results I got indicated that some test cases were failing. The question only gave the following test cases:
stdin:
2 2
1 5
1 5
stdout:
20
stdin:
3 3
1 4 7
2 5 8
3 6 9
stdout:
2160
which my code passses correctly. I did however, go out of my way to attempt to input the maximum values. I wrote a program to print 1000000000 100 times horizontally and 100 times vertically into a text file. However, upon directing the file in, I got a bus error:
$ ./main < data.txt
Bus error (core dumped)
$
Could this be the reason some test cases are failing? Or is the problem elsewhere? Regardless, how would I fix it?
Thank you for your time.
Update: I have found the problem with the bus derror: I forgot to specify the matrix's size when I generated the matrix. It now works, but I found it generates a different result compared to a python3 program, with the C program returning 213129341, whereas the python3 program returned 991047043.
>>> import math
>>> x = pow(10, 9)
>>> xx = x * 100
>>> m = x + 7
>>> r = x
>>> i = 1
>>> while(i < 100):
... i += 1
... r = r * xx
... r = r % m
...
>>> r
991047043
>>> r % m
991047043
>>>
This still doesn't bring me any closer to figuring out why my code is incorrect, unfortunately. Any ideas?
Thank you for your time.
Overflow is possible when multiplying the sums.
Denote the maximal element in the matrix by M (here M = 1000000000, which is approximately 230). M is also approximately equal to your modulo-number. If the matrix is NxN, the sum over a row or column is bounded by M*N. The initialization value for colmulttemp is bounded by M. When multiplying these numbers, we get M2*N as an intermediate result. For M=109 and N=102, this is 1020, which overflows 64-bit numbers.
Fortunately, there is a simple fix - just do your modulo reduction to all your sums, and not only to the first one. Then your intermediate result is bounded by M2, which is just below 264. BTW this is the reason for this particular value of M - it's large enough to make all your numbers impressively big, and small enough to fit intermediate results into 64-bit integers.
for (int col = 0; col < cols; col++) {
coltot[col] %= 1000000007;
}
unsigned long long int colmult,
colmulttemp = coltot[0]; // % 1000000007 not necessary here
Could this be the reason some test cases are failing?
Yes.

Program in C that checks a number's digit subsequences [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 7 years ago.
Improve this question
i need to make a program that for example when given the number 879 must check whether the number is prime and whether all its digits subsequences are prime meaning 87,79,8,7,9 etc. So far i've made a function thats check whether a number is prime but have no idea on how to split a number into its digit subsequences.
Let x be the number. You could first determine the number of digits, n, of x. For example, if x = 543689 then n = 6. This is easily determined by logarithms, for example (available via math.h). Each digit in x has an address ,i, in the range 0,1,...,n-1. It is natural to use a right-to-left ordering so that in the above example i=0 corresponds to the digit 9 rather than 5.
Set up a nested for loop that loops over all pairs of indices i,j with 0 <= i <= j <n. With each pass of the inner loop you need to get the number with starting index i and ending index j. You can do this in two steps
1) Let y = x % (10^(j+1)). This will make y equal to the substring whose leftmost digit is an index j. For example, if x = 543689 and j = 4 then 10^5 = 100000 and 543689 % 100000 = 43689 -- the subsequence starting at index 4.
2) Divide y by 10^i -- this will throw away everything to the right of place i. For example if i=2 and y = 43689 then y / 100 = 436. Note that 436 is the part of 543689 with leftmost index 4 and rightmost index 2.
C doesn't have a built-in power operator. You could appropriately initialize int vars to hold the powers 10^(j+1) and 10^i and update these powers appropriately (by multiplying by 10) in each pass through the loop.
Here is a Python implementation of these ideas (Python since I don't want to give C since this sounds like homework). The only thing that might not be self-explanatory is // -- this is integer division in Python. In C you can just use / -- assuming that you are dealing with int variables:
x = 879
n = 3
for i in range(n):
for j in range(i,n):
y = x % 10**(j+1)
y = y // 10**i
print(y)
Output:
9
79
879
7
87
8
You might use this as well (source: find all subsequences of a number)
#include <stdio.h>
#define NUM 154
int main(void) {
int i,num=NUM,x,y,mask,digits=0,max=1;
while ( num != 0 ) {
num /= 10;
digits++;
}
for ( i = 1; i <= digits; i++ ) {
max *= 2;
}
printf("Subsequences are:\n");
for ( i = 1; i < max - 1 ; i++ ) {
mask = i;
x = 1;
num = NUM;
y=0;
while ( num != 0 ) {
if ( mask % 2 == 1 ) {
y += num % 10 * x;
x *= 10;
}
num /= 10;
mask /= 2;
}
printf("%d \n" , y);
}
return 0;
}
You can use:
void chckdigits(int number)
{
int digits[10]= {0};
int i= 0;
while (number) {
digits[i]= number%10; // array is in reverse
number= number/10;
i++;
}
// now check all permutations
}
#include <stdio.h>
void isPrime(int n){
printf("%d is ...\n", n);
}
int main (void){
int theNumber = 879;
int base = 10;
int n, sub_n;
do {
for(n = theNumber; n >= base/10; n /= 10){
sub_n = n % base;
isPrime(sub_n);
}
base *= 10;
} while(sub_n != theNumber);
return 0;
}

Algorithm for linear equations with more solutions

Can someone help me out with algorithm for solving linear equations in modular arithmetic (!). I need only the "smallest" solution. Smallest means lexicographically first.
Let's have this system:
3x1+2x2=3
4x1+3x2+1x3+2x4=4
Number next to x is index.
Matrix for this system where we use modulo 5 (0<=x<=p where p is our modulo) is
3 2 0 0 0 | 3
4 3 1 2 0 | 4
The smallest solution for this is (0,4,0,1,0). I have to write an algorithm which will give me that solution.
I was thinking about brute-force, because p<1000. But I dont how to do it, because in this situation in first row I have to x1=0 ... p-1 , then solve x2, in the second row i have to pick x3= 0 ... p-1. And solve x4. I have to do this until that system of equations hold. If I go from 0 .. p-1, then the first solution I get will be the smallest one.
PS:There can a lot of forms of matrix, like:
3 2 4 0 0 | 3
4 3 1 2 1 | 4
1 2 0 0 0 | 3
3 0 3 0 0 | 3
4 3 1 2 3 | 4
etc.
Sorry for my english, I am from asia.
Edit: I was thinking about how to determine which variables are parameters. But can't figure it out....
Ah well, what the heck, why not, here you go
#include <stdio.h>
#define L 2
#define N 5
#define MOD 5
static int M[L][N] =
{ { 3, 2, 0, 0, 0 }
, { 4, 3, 1, 2, 0 }
};
static int S[L] =
{ 3, 4
};
static void init(int * s)
{
int i;
for (i = 0; i < N; i++)
{
s[i] = 0;
}
}
static int next(int * s)
{
int i, c;
c = 1;
for (i = N-1; i >= 0 && c > 0; i--)
if ( (++s[i]) == MOD)
{
s[i] = 0;
}
else
{
c = 0;
}
return c == 0;
}
static int is_solution(int * s)
{
int i, j, sum;
for (i = 0; i < L; i++)
{
sum = 0;
for (j = 0; j < N; j++)
{
sum += M[i][j]*s[j];
}
if (sum % MOD != S[i])
{
return 0;
}
}
return 1;
}
int main(void)
{
int s[N];
init(s);
do
{
if (is_solution(s))
{
int i;
for (i = 0; i < N; i++)
{
printf(" %d", s[i]);
}
printf("\n");
break;
}
} while (next(s));
return 0;
}
You can treat this as a problem in linear algebra and Gaussian elimination mod p.
You are trying to find solutions of Mx = y mod p. Start with a square M by adding rows of 0'x = 0 if necessary. Now use Gaussian elimination mod p to reduce M, as far as possible, to upper triangular form. You end up with a system of equations such as
ax + by + cz = H
dy + ez = G
but with some zeros on the diagonal, either because you have run out of equations, or because all of the equations have zero at a particular column. If you have something that says 0z = 1 or similar there is no solution. If not you can work out one of possibly many solutions by solving from the bottom up as usual, and putting in z=0 if there is no equation left that has a non-zero coefficient for z on the diagonal.
I think that this will produce the lexicographically smallest answer if the most significant unknown corresponds to the bottom of the vector. The following shows how you can take an arbitrary solution and make it lexicographically smallest, and I think that you will find that it would not modify solutions produced as above.
Now look at http://en.wikipedia.org/wiki/Kernel_%28matrix%29. There is a linear space of vectors n such that Mn = 0, and all the solutions of the equation are of the form x + n, where n is a vector in this space - the null space - and x is a particular solution, such as the one you have worked out.
You can work out a basis for the null space by finding solutions of Mn = 0 much as you found x. Find a column where there is no non-zero entry on the diagonal, go to the row where the diagonal for that column should be, set the unknown for that column to 1, and move up the matrix from there, choosing the other unknowns so that you have a solution of Mn = 0.
Notice that all of the vectors you get from this have 1 at some position in that vector, 0s below that vector, and possibly non-zero entries above. This means that if you add multiples of them to a solution, starting with the vector which has 1 furthest down, later vectors will never disturb components of the solution where you have previously added in vectors with 1 low down, because later vectors always have zero there.
So if you want to find the lexicographically smallest solution you can arrange things so that you use the basis for the null space with the lexicographically largest entries first. Start with an arbitrary solution and add in null space vectors as best you can, in lexicographical order, to reduce the solution vector. You should end up with the lexicographically smallest solution vector - any solution can be produced from any other solution by adding in a combination of basis vectors from the null space, and you can see from the above procedure that it produces the lexicographically smallest such result - at each stage the most significant components have been made as small as possible and any alternatives must be lexicographically greater.

Resources