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.
Related
I'm currently coding the sieve of Atkin in C++ and it is working well when I'm generating all prime numbers under 50 000 or so but when I try with 50 000 or more the error "Exception thrown: write access violation. prime was 0x828753A3." appears and I can't seem to understand why.
this error appears under the bloc of code where I get rid of multiple of k^2
//get rid of multiple of prime k^2
//start at 5 to skip useless loop with 2 and 3
for (int i = 5; i < n + 1; i++) {
if (prime[i]) {
for (int j = i * i; j <= n; j += i * i) {
prime[j] = false; //Exception thrown: write access violation. prime was 0x828753A3
}
}
}
Here is the full code:
#include <iostream>
using namespace std;
void Atkins(int n) {
bool* prime = new bool[n + 1];
int nbr = 0;
// set all value to false
for (int i = 0; i < n + 1; i++) {
prime[i] = false;
}
//test for all x y combination
for (int x = 1; x*x < n; x++){
for (int y = 1; y * y < n; y++) {
//test three different algorithm possible
int k = 4 * x * x + y * y;
if (k <= n && (k % 12 == 1 || k % 12 == 5)) {
prime[k] = !prime[k];
}
k = 3 * x * x + y * y;
if (k <= n && k % 12 == 7) {
prime[k] = !prime[k];
}
if (x > y) {
k = 3 * x * x - y * y;
if (k <= n && k % 12 == 11) {
prime[k] = !prime[k];
}
}
}
}
//get rid of multiple of prime k^2
//start at 5 to skip useless loop with 2 and 3
for (int i = 5; i < n + 1; i++) {
if (prime[i]) {
for (int j = i * i; j <= n; j += i * i) {
prime[j] = false; //Exception thrown: write access violation. prime was 0x828753A3
}
}
}
//base prime number in list
if (n >= 2) {
cout << "2\n";
nbr++;
}
if (n >= 3) {
cout << "3\n";
nbr++;
}
//print all prime number in list
for (int i = 5; i < n + 1; i++) {
if (prime[i]) {
nbr++;
cout << i << "\n";
}
}
cout << "Il y a " << nbr << " nombre premier entre 0 et " << n << "\n";
delete[] prime;
system("PAUSE");
}
int main() {
Atkins(50000);
return 0;
}
While you're properly guarded all accesses against too big index values, you didn't expect them to be negative.
By running the code under debugger you can see that when error happens, n = -2146737495.
Such value was cause by "integer overflow". When i=46349 -> i*i= 2148229801, which is more than int (32 bit) can take (2^31 - 1).
Simple way is to use long long int data type for multiplication (it has 64 bits, so max value is 2^63 - 1).
int j = i * i; j <= n; j += i * i -> long long int j = (long long int)i * i; j <= n; j += (long long int)i * i.
Several things you need to realize:
On a 32bit platform, INT_MAX is 2147483647. The maximum natural root below that value is 46340 (e.g. root of x^2 = 2147395600.
Automatic representation promotion isn't a language feature. I.e. if you have two int values x=50000 and y=50000, the expression x*y is still int, but because of signed integer overflow, has platform-dependent results. You don't want that.
Yes, you can change the data types to larger 64bit representations, but you don't have to do that. To accommodate the above problem and considerably reduce your workload, understand that you should limit your loops without having to compute i * i or j * j as part of the conditionals. Rather, you can cap the top-end of those loops (and more) using the real thing you're trying to prevent: cross over the square root boundary of n.
For example:
for (int x = 1; x*x < n; x++){
Suppose there was a value nr that was the result of acquiring the integer portion of the square root of n. Then, would what you're really trying to do be better considered as:
int nr = sqrt(n) + 1;
for (int x=1; x < nr; ++x)
So lets do that.
#include <iostream>
#include <cmath>
using namespace std;
void Atkins(int n)
{
bool *prime = new bool[n + 1];
int nbr = 0;
// set all value to false
for (int i = 0; i < n + 1; i++)
{
prime[i] = false;
}
int nr = sqrt(static_cast<double>(n)) + 1;
//test for all x y combination
for (int x = 1; x < nr; x++)
{
for (int y = 1; y < nr; y++)
{
//test three different algorithm possible
int k = 4 * x * x + y * y;
if (k <= n && (k % 12 == 1 || k % 12 == 5))
{
prime[k] = !prime[k];
}
k = 3 * x * x + y * y;
if (k <= n && k % 12 == 7)
{
prime[k] = !prime[k];
}
if (x > y)
{
k = 3 * x * x - y * y;
if (k <= n && k % 12 == 11)
{
prime[k] = !prime[k];
}
}
}
}
//get rid of multiple of prime k^2
//start at 5 to skip useless loop with 2 and 3
for (int i = 5; i < nr; i++)
{
if (prime[i])
{
for (int j = i * i; j <= n; j += i)
{
prime[j] = false; //Exception thrown: write access violation.
}
}
}
//base prime number in list
if (n >= 2)
{
cout << "2\n";
nbr++;
}
if (n >= 3)
{
cout << "3\n";
nbr++;
}
//print all prime number in list
for (int i = 5; i < n + 1; i++)
{
if (prime[i])
{
nbr++;
cout << i << "\n";
}
}
cout << "Il y a " << nbr << " nombre premier entre 0 et " << n << "\n";
delete[] prime;
}
Executing the above version of that function should deliver the results you seek.
See it live here
I'm doing a homework assignment which involves multiplying more than 2 matrices.
I thought about multiplying the first 2 matrices then take its result, continue multiplying it with the 3rd matrix, and repeat the same process until I multiply all the matrices together.
A * B * C = (A * B) * C = A * (B * C)
And here is my code so far. All of my matrices are stored in a 3D array of matrix[1][row][column].
// Calculate the result of first 2 matrices
for (int a = 0; a < n7; a++) {
for (int b = 0; b < n7; b++) {
for (int l = 0; l < n7; l++) {
sum += matrix[1][l][b] * matrix[0][a][l];
}
resultMatrix[a][b] = sum;
sum = 0;
}
}
// Check if k > 2, if yes then continue taking matrix[2] multiply with the result
if (k > 2) {
// Calculate to a tempResult matrix
for (int f = 2; f < k; f++) {
for (int a = 0; a < n7; a++) {
for (int b = 0; b < n7; b++) {
for (int l = 0; l < n7; l++) {
sum += matrix[f][l][b] * resultMatrix[a][l];
}
resultMatrix[a][b] = sum;
sum = 0;
}
}
// Pass the result to the original resultMatrix
for (int a = 0; a < n7; a++) {
for (int b = 0; b < n7; b++) {
resultMatrix[a][b] = tempResult[a][b];
}
}
}
}
I could not get the same result with an online matrix calculator and some manual input.
Please point out my mistakes, thank you!
Here is one solution.. Although I didn't applied dimension check of the matrices. So if you multiply a (3X4) & (2X4) matrix, it will not warn you. It can be done very easily with very simple steps. It worked for me with
A = 1 2 3 4
5 6 7 8 [4X4]
0 1 2 3
7 8 9 0
B = 2 3 4
5 6 7 [4X3]
8 9 0
3 4 5
c = 1
2 [3X1]
3
D = 1 1 -2 -1 [1X4]
Result = 278 278 556 -278
718 718 1436 -718 [4X4]
168 168 336 -168
678 678 1356 -678
The program:
#include <iostream>
#include <iomanip>
void displaymat(double* p, int r, int c)
{
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
std::cout << std::setw(15) << *(p + i * c + j) << "\t";
}
std::cout << std::endl;
}
std::cout << "\n\n" << std::endl;
}
void matrix_multiply(double** a, double* b, int* rf, int* cf, int num)
{
double sum;
double** interim_result = new double* [num - 1]{nullptr};
for (int i = 0; i < num - 1; i++)
{
interim_result[i] = new double[rf[0] * cf[i + 1]]{ 0 };
}
for (int i = 0; i < num - 1; i++)
{
for (int j = 0; j < rf[0]; j++)
{
for (int k = 0; k < cf[i + 1]; k++)
{
sum = 0;
for (int l = 0; l < cf[i]; l++)
{
if (i == 0)
{
sum = sum + a[i][cf[i] * j + l] * a[i + 1][cf[i + 1] * l + k];
}
else
{
sum = sum + interim_result[i - 1][cf[i] * j + l] * a[i + 1][cf[i + 1] * l + k];
}
}
interim_result[i][j * cf[i + 1] + k] = sum;
}
}
//displaymat(interim_result[i], rf[0], cf[i + 1]);
}
for (int i = 0; i < rf[0] * cf[num - 1]; i++)
{
b[i] = interim_result[num - 2][i];
}
for (int i = 0; i < num - 1; i++)
{
delete[] interim_result[i];
}
delete[] interim_result;
}
int main()
{
int num; // total number of matrices
char ch = 'a';
std::cout << "How many matrices/matrix?:";
std::cin >> num;
std::cout << std::endl;
double** mat = new double* [num]; // double pointer for stacks of matrices
int* r = new int[num]{0}; // to store the rows the matrices
int* c = new int[num]{0}; // to store the columns of matrices
for (int n = 0; n < num; n++)
{
std::cout << "matrix:" << n + 1 << "\n" << std::endl;
std::cout << "rows:";
std::cin >> r[n]; // input
std::cout << "columns:";
std::cin >> c[n]; // input
std::cout << std::endl;
mat[n] = new double[(r[n] * c[n])]; // for getting elements
for (int i = 0; i < c[n] * r[n]; i++)
{
std::cout << ch << "[" << i / c[n] + 1 << "][" << i % c[n] + 1 << "]:";//ch << "[" << i / c[n] << "]" << "[" << i % c[n] << "]:";
std::cin >> *(*(mat + n) + i);
}
displaymat(mat[n], r[n], c[n]);
ch++;
}
double* result = new double[r[0] * c[num - 1]];
matrix_multiply(mat, result, r, c, num);
std::cout << "Result=" << std::endl;
displaymat(result, r[0], c[num - 1]);
for (int i = 0; i < num; i++)
{
delete[] * (mat + i);
}
delete[] mat;
delete[] result;
delete[] r;
delete[] c;
}
I Implemented range max sum query using sparse Table ,I Know more efficient approach would be using segment trees.
What I have tried:
I am calculating the max sum in the range (i,2^j-1) for all possible value of i and j and storing them in a table
where i is the index and j denotes the power of 2 (2^j denotes the length of segment from i for which we are calculating max sum)
Now using the above table we can answer the queries
Input:
3
-1 2 3
1
1 2
expected output:
2
actual output:
"wrong answer(garbage value)"
we actually have to tell the max contiguous sum in a given query
Link to the ques spoj gss1
Please help:
#include<iostream>
#include<vector>
#include<algorithm>
#include<climits>
using namespace std;
const int k = 16;
const int N = 1e5;
const int ZERO = 0; // ZERO + x = x + ZERO = x (for any x)
long long table[N][k + 1]; // k + 1 because we need to access table[r][k]
long long Arr[N];
int main()
{
int n, L, R, q;
cin >> n; // array size
for(int i = 0; i < n; i++)
cin >> Arr[i];
// build Sparse Table
for(int i = 0; i < n; i++)
table[i][0] = Arr[i];
for(int j = 1; j <= k; j++) {
for(int i = 0; i <= n - (1 << j); i++)
//table[i][j] = table[i][j - 1] + table[i + (1 << (j - 1))][j - 1];
table[i][j] = max(table[i][j-1],max(table[i+(1<<(j-1))][j-1],table[i+(1<<(j-1))][j-1]+table[i][j-1]));
}
cin >> q; // number of queries
for(int i = 0; i < q; i++) {
cin >> L >> R; // boundaries of next query, 0-indexed
long long int answer = LLONG_MIN;
for(int j = k; j >= 0; j--) {
if(L + (1 << j) - 1 <= R) {
answer = max(answer,answer + table[L][j]);
L += 1 << j; // instead of having L', we increment L directly
}
}
cout << answer << endl;
}
return 0;
}
link to the question Spoj Gss1
Afternoon all, So i am working on the rod cutting problem. Anyone know why this code works when n is hard coded to 7 or some other number in main, but when I grab n via std:cin it does not work and gives all the wrong output... What is going on here?
Here is output from Setting in main int n = 7
18
1 6 -1
While using std in to get n = 7 i get this:
35
1 1 1 1 1 1 1 -1
Price list is the same in both instances....
1
5
8
9
10
17
17
#include <iostream>
#include <cstring>
using namespace std;
const int A = 1000;
int p[A];
int r[A], s[A];
void init() {
p[0] = 0;
p[1] = 1;
p[2] = 5;
p[3] = 8;
p[4] = 9;
p[5] = 10;
p[6] = 17;
p[7] = 17;
p[8] = 20;
p[9] = 24;
p[10] = 30;
}
int extendedButtomUpCutRod(int n) {
for (int j = 1; j <= n; ++j) {
int q = -2145631872;
for (int i = 1; i <= j; ++i)
if (q < p[i] + r[j - i]) {
q = p[i] + r[j - i];
s[j] = i;
}
r[j] = q;
}
return r[n];
}
// prins the extended method's output
void printCutRodSoln(int n) {
do
cout << s[n] << " ";
while ((n -= s[n]) > 0);
}
int main(){
init();
r[0] = 0;
//int n = 7; //works when this is used.
int n;
std::cin >> n; //doesnt work when this is used?
for(int i = 0; i <= n; i++){
std::cin >> p[i];
}
cout << extendedButtomUpCutRod(n) << endl;
printCutRodSoln(n);
std::cout << "-1"<< std::endl;
}
Comments helped but here was the exact line. that needed changing...
for(int i = 1; i <= n; i++),
i = 1 fixed it in all test cases.
Price list was off .
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;
}