I'm solving a algorithm problem https://codeforces.com/contest/1671/problem/E. Although my submit can pass the tests provided by the contest, I find it fails on specific test(Hack). When I'm trying to find where's the error, I find that if I choose start debugging, the program would run perfectly. However, when I click "run", it would give a wrong answer. So, I'm curious about what happens.
#include<iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int const NN = 1e6;
int const MOD = 998244353;
char str[NN];
long long dfs_data[NN];
int powans[20];
string myhash[NN];
int n;
long long dfs(int num) {
if (dfs_data[num] != 0) return dfs_data[num];
if (num >= powans[n - 1] - 1) {
dfs_data[num] = 1;
return 1;
}
if (myhash[num * 2 + 1] == myhash[num * 2 + 2]) {
dfs_data[num] = (dfs(num * 2 + 1) % MOD) * (dfs(num * 2 + 2) % MOD) % MOD;
} else dfs_data[num] = 2 * (dfs(num * 2 + 1) % MOD) * (dfs(num * 2 + 2) % MOD) % MOD;
return dfs_data[num];
}
void gethashcode(int t) {
if (t >= powans[n - 1] - 1) {
myhash[t] += str[t];
return;
}
if (myhash[2 * t + 1] == "") gethashcode(2 * t + 1);
if (myhash[2 * t + 2] == "") gethashcode(2 * t + 2);
if (myhash[2 * t + 1] < myhash[2 * t + 2]) myhash[t] = str[t] + myhash[2 * t + 1] + myhash[2 * t + 2];
else myhash[t] = str[t] + myhash[2 * t + 2] + myhash[2 * t + 1];
}
void solve() {
memset(dfs_data, 0, sizeof dfs_data);
cin >> n;
cin >> str;
powans[0] = 1;
for (int i = 1; i < 19; i++) {
powans[i] = 2 * powans[i - 1];
}
for (int i = 0; i < NN; i++) {
myhash[i] = "";
}
gethashcode(0);
cout << dfs(0);
}
int main() {
solve();
}
Related
I am coding a solution program for leetcode. I have encountered memory read errors and segmentation fault errors which I am unable to resolve. I have tried tinkering with the code to try and remove the errors.
For example: in the numIslands function's last lines, I had tried declaring coordinates as an array rather than a pointer but the results did not change.
*(last + 1) = *(coordinates + 1); does not seem to work at all in the numIslands function. I am totally blank about what to do next.
#include <iostream>
#include <string>
#include <vector>
#include <map>
namespace p200 {
using std::cout;
using std::cin;
using std::endl;
using std::string;
using std::vector;
using std::map;
}
class Solution {
private:
int count_islands = 0;
public:
int *last;
int numIslands(vector<vector<char>>& grid) {
if (grid.size() == 0) return count_islands;
if (grid.size() == 1 && grid[0].size() == 1) return grid[0][0] - 48;
vector<vector<int>> grid_copy;
vector<int> in;
for (size_t index = 0; index < grid.size(); ++index) {
for (size_t index0 = 0; index0 < grid[index].size(); ++index0) {
(grid[index][index0] == '0')
? in.push_back(0)
: in.push_back(INT_MAX);
}
grid_copy.push_back(in);
in.clear();
}
int * coordinates = new int[2];
*coordinates = 0;
*(coordinates + 1) = 0;
last = new int[2];
*last = *coordinates;
*(last + 1) = *(coordinates + 1);
find_island(grid_copy, coordinates);
return count_islands;
}
void find_island(vector<vector<int>> & arg_grid, int* arg_coordinates) {
if (arg_grid[*arg_coordinates][*(arg_coordinates + 1)] == INT_MAX) {
*last = *arg_coordinates;
*(last + 1) = *(arg_coordinates + 1);
map_island(arg_grid, arg_coordinates, 1);
} else {
if (*(arg_coordinates + 1) < arg_grid[*arg_coordinates].size()) {
*(arg_coordinates + 1) = *(arg_coordinates + 1) + 1;
find_island(arg_grid, arg_coordinates);
}
if (*(arg_coordinates + 1) == arg_grid[*arg_coordinates].size()) {
if (*arg_coordinates == arg_grid.size()) return;
*arg_coordinates = *arg_coordinates + 1;
*(arg_coordinates + 1) = 0;
find_island(arg_grid, arg_coordinates);
}
}
}
void map_island(vector<vector<int>> & arg_grid, int* arg_coordinates, int arg_new) {
arg_grid[*arg_coordinates][*(arg_coordinates + 1)] = count_islands + (arg_new * 1);
if (arg_new) count_islands = count_islands + 1;
if (*arg_coordinates != 0 && *arg_coordinates - 1 == INT_MAX) {
*arg_coordinates = *arg_coordinates - 1;
map_island(arg_grid, arg_coordinates, 0);
*arg_coordinates = *arg_coordinates + 1;
}
if ((*arg_coordinates < arg_grid.size() - 1)
&& *arg_coordinates + 1 == INT_MAX) {
*arg_coordinates = *arg_coordinates + 1;
map_island(arg_grid, arg_coordinates, 0);
*arg_coordinates = *arg_coordinates - 1;
}
if (*(arg_coordinates + 1) != 0 && *(arg_coordinates + 1) - 1 == INT_MAX) {
*(arg_coordinates + 1) = *(arg_coordinates + 1) - 1;
map_island(arg_grid, arg_coordinates, 0);
*(arg_coordinates + 1) = *(arg_coordinates + 1) + 1;
}
if (*(arg_coordinates + 1) < arg_grid[*arg_coordinates].size() - 1
&& *(arg_coordinates + 1) + 1 == INT_MAX) {
*(arg_coordinates + 1) = *(arg_coordinates + 1) + 1;
map_island(arg_grid, arg_coordinates, 0);
*(arg_coordinates + 1) = *(arg_coordinates + 1) - 1;
}
find_island(arg_grid, last);
}
};
int main() {
vector<vector<char>> input;
input.push_back(vector<char>({'1','1','1','1','0'}));
input.push_back(vector<char>({'1','1','0','1','0'}));
input.push_back(vector<char>({'1','1','0','0','0'}));
input.push_back(vector<char>({'0','0','0','0','0'}));
Solution solver;
cout << "Number of Island: " << solver.numIslands(input) << endl;
return 0;
}
I have ran it through gdb. After a bit of digging, the error is this:
void find_island(vector<vector<int>> & arg_grid, int* arg_coordinates) {
if (arg_grid[*arg_coordinates][*(arg_coordinates + 1)] == INT_MAX) {
*last = *arg_coordinates;
*(last + 1) = *(arg_coordinates + 1);
map_island(arg_grid, arg_coordinates, 1);
} else {
if (*(arg_coordinates + 1) < arg_grid[*arg_coordinates].size()) {
*(arg_coordinates + 1) = *(arg_coordinates + 1) + 1;
find_island(arg_grid, arg_coordinates);
}
if (*(arg_coordinates + 1) == arg_grid[*arg_coordinates].size()) {
if (*arg_coordinates == arg_grid.size()) return;
*arg_coordinates = *arg_coordinates + 1;
*(arg_coordinates + 1) = 0;
find_island(arg_grid, arg_coordinates);
}
}
}
In the second if, you do a bounds check and then increment. You should first increment then to the bounds check, like this:
*arg_coordinates = *arg_coordinates + 1;
if (*arg_coordinates == arg_grid.size()) return;
Also please usevector.at() instead of operator[]. It produces more readable and easier to interpret debug messages. Also as other people pointed it out *(arg_coordinates + 1) = arg_coordinates[1], which would make for a more readable code.
For other similar issues I recommend a debugger.
Edit: I ran the code and realised that there is some other bug within it. One of the islands is counted twice, so it gives the wrong result, but that is not technically the issue at hand.
I am creating a script that calculates the sum of first n Fibonacci numbers and returns the last digit of the sum.
The python script works perfect but the C++ script does not and the logic is same.
Any help will be appreciated.
Python Code
def calc_fib(n):
f = [0, 1]
for i in range(2, 61):
f.insert(i, (f[i-1] + f[i-2]) % 10)
rem = n % 60
quotient = (n - rem) / 60
return int((sum(f) * quotient + sum(f[0: rem+1])) % 10)
n = int(input())
print(calc_fib(n))
C++ Code
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
long long fibonacci_sum_last_digit(long long n) {
vector<int> f(n + 1);
f[0] = 0;
f[1] = 1;
for (int i = 2; i <= 60; i++){
f[i] = (f[i-1] + f[i-2]) % 10;
}
int rem = n % 60;
int quotient = (n - rem) / 60;
return (accumulate(f.begin(), f.end(), 0) * quotient + accumulate(f.begin(), f.begin() + rem + 1, 0)) % 10;
}
int main() {
int n;
cin >> n;
if (n <= 1)
cout << n;
else
cout << fibonacci_sum_last_digit(n) << '\n';
return 0;
}
vector<int> f(n + 1);
f[0] = 0;
f[1] = 1;
for (int i = 2; i <= 60; i++){
f[i] = (f[i-1] + f[i-2]) % 10;
}
The vector is size n+1 and you access until 60 => it's a bug
This should fix :
vector<int> f(60 + 1);
Or
vector<int> f;
f.push_back(0);
f.push_back(1);
for (int i = 2; i <= 60; i++){
f.push_back((f[i-1] + f[i-2]) % 10);
}
I've been struggling to understand how the function long long number here works. The bit that I can't fully grasp is the for cycles in the if's. Why when we have a number in dec do we have to raise it to that power? Shouldn't we just sum it up and leave it? Also why do we raise the other numbers to that power?
Here is the code:
int counter(long long n, int k) {
int counter = 0;
while (n != 0) {
counter++;
n /= k;
}
return counter;
}
int number2(long long n, int number) {
return (n / (long long) pow(10, number)) % 10;
}
int toDecimal(long long n, int k) {
long long decimal = 0;
for (int i = 0; i < counter(n, 10); i++) {
decimal += number2(n, i)*(int)pow(k, i);
}
return decimal;
}
long long number(char *arr, int start) {
int end = start;
long long number2 = 0;
while (*(arr + end) != ' ' && *(arr + end) != '\0') {
end++;
}
int numberSize = end - start;
if (*(arr + start) != '0') {
for (int i = 0; i < numberSize; i++) {
number2 += (*(arr + start + i) - '0')*pow(10, numberSize - i - 1);
}
return number2;
}
if (*(arr + start) == '0' && (*(arr + start + 1) != 'b' && *(arr + start + 1) != 'x')) {
for (int i = 1; i < numberSize; i++) {
number2 += (*(arr + start + i) - '0')*pow(10, numberSize - i - 1);
}
return toDecimal(number2, 8);
}
if (*(arr + start) == '0' && *(arr + start + 1) == 'b') {
for (int i = 2; i < numberSize; i++) {
number2 += (*(arr + start + i) - '0')*pow(10, numberSize - i - 1);
}
return toDecimal(number2, 2);
}
if (*(arr + start) == '0' && *(arr + start + 1) == 'x') {
int *hex = new int[numberSize - 2];
for (int i = 2; i < numberSize; i++) {
if (*(arr + start + i) >= '0'&&
*(arr + start + i) <= '9')
arr[i - 2] = (*(arr + start + i) - '0');
if (*(arr + start + i) >= 'A'&&
*(arr + start + i) <= 'F')
arr[i - 2] = (int)(*(arr + start + i) - '7');
number2 += arr[i - 2] * pow(16, numberSize - i - 1);
}
delete[] hex;
return number2;
}
}
int main() {
char first[1000];
cin.getline(first, 1000);
int size = strlen(first);
long numberr = number(&first[0], 0);
for (int counter = 0; counter < size; counter++) {
if (first[counter] == ' '&&first[counter + 1] == '+') {
numberr += number(&first[0], counter + 3);
}
}
cout << numberr << "\n";
return 0;
}
The number is a string and is a sequence of single characters representing digits. You have to convert the characters to numbers ("1" --> 1) and then multiply it by the right number of tens to move it to the right place. For example: "123" --> (1 * 10^2) + (2 * 10^1) + (3 * 10^0)
So I got this introduction to Programming assignment, I have to write a program that find the nth member of the following sequence 1, 121, 1213121, 121312141213121.. and so on. Basically, the first member is 1, and every next one is made of [the previous member] [n] [the previous member]. N < 10. So I got this problem that I do not understand, tried searching for it in the internet but didn't get anything that can help me.
#include "stdafx.h"
#include <iostream>
using namespace std;
int size(int n, int realsize);
int main()
{
int n;
cin >> n;
if (n == 1) {
cout << "1";
return 0;
}
int helper = 0;
char c = '2';
char* look;
char* say;
say = new char[size(n, 1) + 1]();
look = new char[size(n - 1, 1) + 1]();
look[0] = '1';
while (helper < n) {
for (int i = 0; i < size(helper + 1, 1); i++) {
say[i] = look[i];
}
say[size(helper + 1, 1)] = c;
for (int i = size(helper + 1, 1) + 1; i < size(helper + 1, 1) * 2 + 1; i++) {
say[i] = look[i - (size(helper + 1, 1) + 1)];
}
for (int i = 0; i < size(helper + 1, 1) * 2 + 1; i++) {
look[i] = say[i];
}
helper += 1;
}
cout << say;
delete[] say;
delete[] look;
return 0;
}
int size(int n, int realsize)
{
if (n == 1)
return realsize;
else
return size(n - 1, realsize * 2 + 1);
}
You are overwriting the capacity of your look variable. It ends out being written with the entire contents of say, so it needs to have that same size as well.
While I don't condone the below code as good code, it has minimal adjustments from your own implementation and should give a more solid base to continue towards a working outcome. I tested it with the first couple of numbers, but that's no guarantee it is perfect.
#include <iostream>
using namespace std;
int size(int n, int realsize);
int main()
{
int n;
cin >> n;
if (n == 1)
{
cout << "1";
return 0;
}
int helper = 0;
char c = '2';
char * look;
char * say;
say = new char[size(n, 1) + 1]; // Ditch the () call, which is confusing.
look = new char[size(n, 1) + 1]; // Make the same size as "say"
look[0] = '1';
while (helper < n - 1) // You're overrunning this loop I think, so I did it to n - 1.
{
for (int i = 0; i < size(helper + 1, 1); i++)
{
say[i] = look[i];
}
say[size(helper + 1, 1)] = c + helper; // You were adding '2' every time, so this will add 2, 3, 4, etc incrementally.
for (int i = size(helper + 1, 1) + 1; i < size(helper + 1, 1) * 2 + 1; i++)
{
say[i] = look[i - (size(helper + 1, 1) + 1)];
}
for (int i = 0; i < size(helper + 1, 1) * 2 + 1; i++)
{
look[i] = say[i];
}
helper += 1;
}
say[size(n, 1)] = '\0'; // Null-terminate "say" before printing it out.
cout << say;
delete[] say;
delete[] look;
return 0;
}
int size(int n, int realsize)
{
if (n == 1)
return realsize;
else
return size(n - 1, realsize * 2 + 1);
}
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 9 years ago.
Consider the following code:
int* solve(int input[], int len) {
//Processing and building the calc array. Can be ignored.
int calc[3*(len-1)];
calc[0] = input[0];
calc[1] = 1;
calc[2] = 1;
for (int b = 1; b < len - 1; b++) {
calc[3*b] = 0;
calc[3*b + 1] = 0;
calc[3*b + 2] = 0;
}
if (input[0] < input[1]) {
calc[3] = input[1];
calc[4] = 0;
calc[5] = 1;
} else {
calc[3] = input[0];
calc[4] = 1;
calc[5] = 0;
}
for (int i = 2; i < len - 1; i++) {
for (int j = 0; j < i; j++) {
if ((i - j > 1 || calc[3*j + 2] == 0) && calc[3*j] + input[i] > calc[3*i]) {
calc[3*i] = calc[3*j] + input[i];
calc[3*i + 1] = calc[3*j + 1];
calc[3*i + 2] = 1;
} else if (input[i] > input[j] && calc[3*i] < calc[3*j] - input[j] + input[i]) {
calc[3*i] = calc[3*j] - input[j] + input[i];
calc[3*i + 1] = calc[3*j + 1];
calc[3*i + 2] = 1;
} else if (calc[3*i] < calc[3*j]) {
calc[3*i] = calc[3*j];
calc[3*i + 1] = calc[3*j + 1];
calc[3*i + 2] = 0;
}
}
}
//Printing the array
cout<<"Calc array: ";
for (int a = 0; a < len - 1; a++) {
cout<<"("<<calc[3*a]<<" "<<calc[3*a + 1]<<" "<<calc[3*a+2]<<") ";
}
cout<<endl;
//Returning a pointer to the array
int *pointer = calc;
return pointer;
}
int main() {
//Taking input. Can be ignored.
int len;
cin>>len;
int input[len];
for (int i = 0; i < len; i++) {
cin>>input[i];
}
//Assigning another pointer to the array that the solve() function returns.
int *a = solve(input, len);
int *b;
//Printing the array that the pointer points to.
cout<<"A Array: ";
for (int x = 0; x < len - 1; x++) {
cout<<"("<<a[3*x]<<" "<<a[3*x + 1]<<" "<<a[3*x+2]<<") ";
}
cout<<endl;
//Ignore code from here.
int c;
if (a[3*(len - 2) + 1] == 1) {
input[0] = -10*10*10*10;
b = solve(input, len);
if (b[3*(len - 2) + 2] == 1) {
if (input[len-1] > input[len-2]) {
c = b[3*(len - 2)] - input[len-2] + input[len - 1];
cout<<c<<endl;
} else {
c = b[3*(len - 2)];
}
} else {
c = b[3*(len - 2)] + input[len-1];
}
if (c < a[3*(len - 2)]) {
cout<<a[3*(len - 2)];
} else {
cout<<c<<endl;
cout<<a[3*(len - 2)]<<" "<<a[3*(len - 2) + 1]<<" "<<a[3*(len - 2) + 2];
cout<<"This route"<<endl;
}
} else {
input[1] = -10*10*10*10;
b = solve(input, len);
if (a[3*(len - 2) + 2] == 1) {
if (input[len-1] > input[len-2]) {
c = a[3*(len - 2)] - input[len-2] + input[len - 1];
} else {
c = a[3*(len - 2)];
}
} else {
c = a[3*(len - 2)] + input[len-1];
}
if (c > b[3*(len - 2)]) {
cout<<b[3*(len - 2)];
} else {
cout<<c;
}
}
}
Now the problem here is, that when I print the calc array inside the solve() function the first time it prints perfectly and gives the following desired output:
Calc array: (10 1 1) (10 1 0) (12 1 1) (15 1 1) (19 1 1)
But when I print it again inside the main() function, I get the following output:
A Array: (135712 0 1259266624) (2045 1 0) (4792936 0 32) (15 4792936 0) (2357952 0 4792936)
I have just migrated from Python to C++, and I find it extremely cumbersome, at times such as these. I have tried all sorts of modifications to the code but I still can't figure out the problem. Any help would be appreciated.
calc is a local variable whose lifetime starts at it's definition and ends when the function exits.
Since you're returning a pointer to it when exiting the function, the dereferencing of said pointer will be undefined behaviour (since the "object" behind it no longer exists).
If you want a variable to survive function return, you'll need to do something like allocating it dynamically, changing:
int calc[3*(len-1)];
to:
int *calc = new int [(3 * (len - 1)];
and then ensuring you delete[] it in the caller when you're done with it.