I am getting this kind of weird error, I wrote a function to find the minimum sub array sum. But this doesn't work when the values of array start from 1 to size for value 1 2 3 4. I get timeout, but same code for 1 2 3 4 5 gives the correct answer. If I put a statement print statement above min_sub_array it gives the right answer for all values. It also works fine when the values start from 0 to size - 1
int min_sub_array_sum(int d[], int size)
{
for(int i = 1; i <= size; i++)
d[i] = -d[i];
int max_end_i = d[1], max_so_far = d[1];
for(int i = 2; i <= size; i++)
{
max_end_i += d[i];
if(max_so_far < max_end_i)
max_so_far = max_end_i;
if(max_end_i < 0)
max_end_i = 0;
}
return (-max_so_far);
}
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
int d[n];
for(int i = 1; i <= n; i++)
cin>>d[i];
cout<<min_sub_array_sum(d, n)<<'\n';
}
}
I should get the value of 1 for 1 2 3 4. But I am not getting.
You are accessing the nth index of array d[n] which does not exist.
Related
I want to find the sum of all the positive integers in the range [1, N] with a given digit sum d. For example, if n = 100 and d = 7, the answer will be 7 + 16 + 25 + 34 + 43 + 52 + 61 + 70 = 308.
Following code can be used to count the numbers in the range [1, N] with a given digit sum d.
cnt[i][0][s] denotes count of suffixes that can be formed starting from index i, whose digits add up to s.
cnt[i][1][s] count of suffixes that can be formed starting from index i, whose digits add up to s such that the formed suffix is not greater than corresponding suffix in input string
#include <bits/stdc++.h>
using namespace std;
typedef long long int i64;
i64 cnt[20][2][200];
void digit_sum_dp(string ss) {
int n = ss.size();
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 200; k++) {
cnt[i][j][k] = 0;
}
}
}
cnt[n][0][0] = 1;
cnt[n][1][0] = 1;
for (int i = n - 1; i >= 0; i--) {
for (int tight = 0; tight < 2; tight++) {
for (int sum = 0; sum < 200; sum++) {
if (tight) {
for (int d = 0; d <= ss[i] - '0'; d++) {
if (d == ss[i] - '0') {
cnt[i][1][sum] += cnt[i + 1][1][sum - d];
} else {
cnt[i][1][sum] += cnt[i + 1][0][sum - d];
}
}
} else {
for (int d = 0; d < 10; d++) {
cnt[i][0][sum] += cnt[i + 1][0][sum - d];
}
}
}
}
}
return cnt[0][1][d];
}
int main() {
string str = "100";
int d = 7;
cout << digit_sum_dp(str, d) << "\n";
return 0;
}
I have tried to extend the code to find out the sum of numbers instead of the count of numbers. Following is a code snippet.
cnt[i][1][sum] += cnt[i + 1][1][sum - d];
tot[i][1][sum] += (d * cnt[i + 1][1][sum - d] + tot[i + 1][1][sum - d] * pow(10, i));
I am getting incorrect results for some of the inputs. I shall be grateful if someone can help me.
I am using 1D array to get the final answer, but I also need to get selected items. How to achieve that?
private static int UnboundedKnapsack(int capacity, int n, int[] itemValue, int[] itemWeight)
{
int[] dp = new int[capacity + 1];
for (int i = 0; i <= capacity; i++)
{
for (int j = 0; j < n; j++)
{
if (itemWeight[j] <= i)
{
dp[i] = Math.Max(dp[i], dp[i - itemWeight[j]] + itemValue[j]);
}
}
}
return dp[capacity];
}
Let's introduce a new path function that gives the optimal selcetions of items using the previously calculated dp array.
private static void path(int capacity, int n, int[] itemValue, int[] itemWeight, int[] dp){
if(capacity == 0) return; // here you handle when the function will end. I assume capacity should be empty at the last
int ans = 0, chosenItem;
for(int j = 0; j < n; j++){
int newAns = dp[capacity - itemWeight[j]] + itemValue[j];
if(newAns > ans){
ans = newAns;
chosenItem = j;
}
}
printf("%d ",chosenItem); // here you get the current item you need to select;
path(capacity - itemWeight[chosenItem], n, itemValue, itemWeight, dp);
}
This program checks distinctness in an array. (no repeated values in an array I.e if 1 2 3 3 4 is an array it is not distinct). this code Won't compile although (I believe that) index of array did not go out of range in for loop.
theRun-Time Check Failure says stack around variable 'n' was corrupted when I enter n =12. BUT says stack around variable 'A' was corrupted when I enter n = 10. with exactly the same variables entered in the array in the second step. (the error shows up after entering the fourth integer)
#include <iostream>
using namespace std;
int main()
{
int n;
int A[] = {0};
int integer;
cout<<"Enter the size of the array\n";
cin>>n;
cout<<"enter "<<n<<" integers\n";
for (int i = 0 ; i < n ; i++)
{
cin>>A[i];
}
for (int i = 0 ; i < n ; i++)
{
for (int j = 0 ; j < n - i; j++)
{
if(A[j+1] > A[j])
{
int temp;
temp = A[j];
A[j+1] = A[j];
A[j+1] = temp;
}
}
}
for (int i = 0 ; i < n; i++)
{
if (A[i] - A[i+1] ==0 ){
cout<<"\nThe Array Is Not Distinct !\n";
break;
}
else
{
cout<<"\nThe Array Is Distinct !\n";
}
}
system("pause");
return 0;
}
I executed the following code on Ubuntu 14.04 and CentOS 7 using gcc compiler but the strange thing is that it shows different output for same inputs. There are two issues that I'm unable to solve.
I always get 0 in sum(in main function) for the very first multiplication (1*1).
Completely unexpected output for Ubuntu.
Here is the code and both the outputs.
Code
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#define N 15
struct matrix
{
int num1, num2;
};
void* multiply(void *c);
int main()
{
int i, j, rows, cols, a[N][N], b[N][N], sum, k, final, res[N][N],*ptr;
pthread_t t1, t2;
struct matrix m1;
ptr=∑
printf("Enter the number of rows: ");
scanf("%d", &rows);
printf("Enter the number of cols: ");
scanf("%d", &cols);
for(i = 0; i < rows; i++)
{
for(j = 0; j < cols; j++)
{
printf("Enter the value at: a[%d][%d] : ", i, j);
scanf("%d", &a[i][j]);
}
}
for(i = 0; i < rows; i++)
{
for(j = 0; j < cols; j++)
{
printf("Enter the value at: b[%d][%d] : ", i, j);
scanf("%d", &b[i][j]);
}
}
for(i = 0; i < rows; i++)
{
for(j = 0; j < cols; j++)
{
final = 0;
for(k = 0; k < rows; k++)
{
m1.num1 = a[i][k];
m1.num2 = b[k][j];
pthread_create(&t1, NULL, (void*)multiply,(void*)&m1);
pthread_join(t1, (void**)&ptr);
sum=*ptr;
printf("\t%d",sum);
final += sum;
res[i][j] = final;
}
printf("\n");
}
}
printf("The result is :\n");
for(i = 0; i < rows; i++)
{
for(j = 0; j < cols; j++)
{
printf("%d\t", res[i][j]);
}
printf("\n");
}
return 0;
}
void* multiply(void *c)
{
struct matrix *m;
m = (struct matrix *)c;
int p = 0;
p = m->num1 * m->num2;
printf("\t%d * %d = %d",m->num1,m->num2,p);
pthread_exit((void*)&p);
}
Output for execution on Ubuntu
Enter the number of rows: 2
Enter the number of cols: 2
Enter the value at: a[0][0] : 1
Enter the value at: a[0][1] : 2
Enter the value at: a[1][0] : 3
Enter the value at: a[1][1] : 4
Enter the value at: b[0][0] : 1
Enter the value at: b[0][1] : 2
Enter the value at: b[1][0] : 3
Enter the value at: b[1][1] : 4
1 * 1 = 1 0 2 * 3 = 6 32648
1 * 2 = 2 32648 2 * 4 = 8 32648
3 * 1 = 3 32648 4 * 3 = 12 32648
3 * 2 = 6 32648 4 * 4 = 16 32648
The result is :
32648 65296
65296 65296
Output for execution on CentOS
Enter the number of rows: 2
Enter the number of cols: 2
Enter the value at: a[0][0] : 1
Enter the value at: a[0][1] : 2
Enter the value at: a[1][0] : 3
Enter the value at: a[1][1] : 4
Enter the value at: b[0][0] : 1
Enter the value at: b[0][1] : 2
Enter the value at: b[1][0] : 3
Enter the value at: b[1][1] : 4
1 * 1 = 1 0 2 * 3 = 6 6
1 * 2 = 2 2 2 * 4 = 8 8
3 * 1 = 3 2 4 * 3 = 12 4
3 * 2 = 6 3 4 * 4 = 16 16
The result is :
6 10
15 22
The multiply function is returning a pointer to a local variable p, and the lifetime of the local variable finishes as soon as the function ends.
The easiest solution here is not to use the return value, but to reserve a place for the result in the struct matrix that is passed to multiply(), because that structure is allocated within main. Change the definition of struct multiply:
struct matrix
{
int num1, num2;
int product;
};
Change multiply() to put the result here:
void *multiply(void *c)
{
struct matrix *m = c;
m->product = m->num1 * m->num2;
printf("\t%d * %d = %d", m->num1, m->num2, m->product);
return NULL;
}
Change main() to retrieve the result from there:
pthread_create(&t1, NULL, multiply, &m1);
pthread_join(t1, NULL);
sum = m1.product;
(Side note: that variable sum has a confusing name, since it doesn't hold a sum!)
I'm posting this although much has already been posted about this question. I didn't want to post as an answer since it's not working. The answer to this post (Finding the rank of the Given string in list of all possible permutations with Duplicates) did not work for me.
So I tried this (which is a compilation of code I've plagiarized and my attempt to deal with repetitions). The non-repeating cases work fine. BOOKKEEPER generates 83863, not the desired 10743.
(The factorial function and letter counter array 'repeats' are working correctly. I didn't post to save space.)
while (pointer != length)
{
if (sortedWordChars[pointer] != wordArray[pointer])
{
// Swap the current character with the one after that
char temp = sortedWordChars[pointer];
sortedWordChars[pointer] = sortedWordChars[next];
sortedWordChars[next] = temp;
next++;
//For each position check how many characters left have duplicates,
//and use the logic that if you need to permute n things and if 'a' things
//are similar the number of permutations is n!/a!
int ct = repeats[(sortedWordChars[pointer]-64)];
// Increment the rank
if (ct>1) { //repeats?
System.out.println("repeating " + (sortedWordChars[pointer]-64));
//In case of repetition of any character use: (n-1)!/(times)!
//e.g. if there is 1 character which is repeating twice,
//x* (n-1)!/2!
int dividend = getFactorialIter(length - pointer - 1);
int divisor = getFactorialIter(ct);
int quo = dividend/divisor;
rank += quo;
} else {
rank += getFactorialIter(length - pointer - 1);
}
} else
{
pointer++;
next = pointer + 1;
}
}
Note: this answer is for 1-based rankings, as specified implicitly by example. Here's some Python that works at least for the two examples provided. The key fact is that suffixperms * ctr[y] // ctr[x] is the number of permutations whose first letter is y of the length-(i + 1) suffix of perm.
from collections import Counter
def rankperm(perm):
rank = 1
suffixperms = 1
ctr = Counter()
for i in range(len(perm)):
x = perm[((len(perm) - 1) - i)]
ctr[x] += 1
for y in ctr:
if (y < x):
rank += ((suffixperms * ctr[y]) // ctr[x])
suffixperms = ((suffixperms * (i + 1)) // ctr[x])
return rank
print(rankperm('QUESTION'))
print(rankperm('BOOKKEEPER'))
Java version:
public static long rankPerm(String perm) {
long rank = 1;
long suffixPermCount = 1;
java.util.Map<Character, Integer> charCounts =
new java.util.HashMap<Character, Integer>();
for (int i = perm.length() - 1; i > -1; i--) {
char x = perm.charAt(i);
int xCount = charCounts.containsKey(x) ? charCounts.get(x) + 1 : 1;
charCounts.put(x, xCount);
for (java.util.Map.Entry<Character, Integer> e : charCounts.entrySet()) {
if (e.getKey() < x) {
rank += suffixPermCount * e.getValue() / xCount;
}
}
suffixPermCount *= perm.length() - i;
suffixPermCount /= xCount;
}
return rank;
}
Unranking permutations:
from collections import Counter
def unrankperm(letters, rank):
ctr = Counter()
permcount = 1
for i in range(len(letters)):
x = letters[i]
ctr[x] += 1
permcount = (permcount * (i + 1)) // ctr[x]
# ctr is the histogram of letters
# permcount is the number of distinct perms of letters
perm = []
for i in range(len(letters)):
for x in sorted(ctr.keys()):
# suffixcount is the number of distinct perms that begin with x
suffixcount = permcount * ctr[x] // (len(letters) - i)
if rank <= suffixcount:
perm.append(x)
permcount = suffixcount
ctr[x] -= 1
if ctr[x] == 0:
del ctr[x]
break
rank -= suffixcount
return ''.join(perm)
If we use mathematics, the complexity will come down and will be able to find rank quicker. This will be particularly helpful for large strings.
(more details can be found here)
Suggest to programmatically define the approach shown here (screenshot attached below) given below)
I would say David post (the accepted answer) is super cool. However, I would like to improve it further for speed. The inner loop is trying to find inverse order pairs, and for each such inverse order, it tries to contribute to the increment of rank. If we use an ordered map structure (binary search tree or BST) in that place, we can simply do an inorder traversal from the first node (left-bottom) until it reaches the current character in the BST, rather than traversal for the whole map(BST). In C++, std::map is a perfect one for BST implementation. The following code reduces the necessary iterations in loop and removes the if check.
long long rankofword(string s)
{
long long rank = 1;
long long suffixPermCount = 1;
map<char, int> m;
int size = s.size();
for (int i = size - 1; i > -1; i--)
{
char x = s[i];
m[x]++;
for (auto it = m.begin(); it != m.find(x); it++)
rank += suffixPermCount * it->second / m[x];
suffixPermCount *= (size - i);
suffixPermCount /= m[x];
}
return rank;
}
#Dvaid Einstat, this was really helpful. It took me a WHILE to figure out what you were doing as I am still learning my first language(C#). I translated it into C# and figured that I'd give that solution as well since this listing helped me so much!
Thanks!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
namespace CsharpVersion
{
class Program
{
//Takes in the word and checks to make sure that the word
//is between 1 and 25 charaters inclusive and only
//letters are used
static string readWord(string prompt, int high)
{
Regex rgx = new Regex("^[a-zA-Z]+$");
string word;
string result;
do
{
Console.WriteLine(prompt);
word = Console.ReadLine();
} while (word == "" | word.Length > high | rgx.IsMatch(word) == false);
result = word.ToUpper();
return result;
}
//Creates a sorted dictionary containing distinct letters
//initialized with 0 frequency
static SortedDictionary<char,int> Counter(string word)
{
char[] wordArray = word.ToCharArray();
int len = word.Length;
SortedDictionary<char,int> count = new SortedDictionary<char,int>();
foreach(char c in word)
{
if(count.ContainsKey(c))
{
}
else
{
count.Add(c, 0);
}
}
return count;
}
//Creates a factorial function
static int Factorial(int n)
{
if (n <= 1)
{
return 1;
}
else
{
return n * Factorial(n - 1);
}
}
//Ranks the word input if there are no repeated charaters
//in the word
static Int64 rankWord(char[] wordArray)
{
int n = wordArray.Length;
Int64 rank = 1;
//loops through the array of letters
for (int i = 0; i < n-1; i++)
{
int x=0;
//loops all letters after i and compares them for factorial calculation
for (int j = i+1; j<n ; j++)
{
if (wordArray[i] > wordArray[j])
{
x++;
}
}
rank = rank + x * (Factorial(n - i - 1));
}
return rank;
}
//Ranks the word input if there are repeated charaters
//in the word
static Int64 rankPerm(String word)
{
Int64 rank = 1;
Int64 suffixPermCount = 1;
SortedDictionary<char, int> counter = Counter(word);
for (int i = word.Length - 1; i > -1; i--)
{
char x = Convert.ToChar(word.Substring(i,1));
int xCount;
if(counter[x] != 0)
{
xCount = counter[x] + 1;
}
else
{
xCount = 1;
}
counter[x] = xCount;
foreach (KeyValuePair<char,int> e in counter)
{
if (e.Key < x)
{
rank += suffixPermCount * e.Value / xCount;
}
}
suffixPermCount *= word.Length - i;
suffixPermCount /= xCount;
}
return rank;
}
static void Main(string[] args)
{
Console.WriteLine("Type Exit to end the program.");
string prompt = "Please enter a word using only letters:";
const int MAX_VALUE = 25;
Int64 rank = new Int64();
string theWord;
do
{
theWord = readWord(prompt, MAX_VALUE);
char[] wordLetters = theWord.ToCharArray();
Array.Sort(wordLetters);
bool duplicate = false;
for(int i = 0; i< theWord.Length - 1; i++)
{
if(wordLetters[i] < wordLetters[i+1])
{
duplicate = true;
}
}
if(duplicate)
{
SortedDictionary<char, int> counter = Counter(theWord);
rank = rankPerm(theWord);
Console.WriteLine("\n" + theWord + " = " + rank);
}
else
{
char[] letters = theWord.ToCharArray();
rank = rankWord(letters);
Console.WriteLine("\n" + theWord + " = " + rank);
}
} while (theWord != "EXIT");
Console.WriteLine("\nPress enter to escape..");
Console.Read();
}
}
}
If there are k distinct characters, the i^th character repeated n_i times, then the total number of permutations is given by
(n_1 + n_2 + ..+ n_k)!
------------------------------------------------
n_1! n_2! ... n_k!
which is the multinomial coefficient.
Now we can use this to compute the rank of a given permutation as follows:
Consider the first character(leftmost). say it was the r^th one in the sorted order of characters.
Now if you replace the first character by any of the 1,2,3,..,(r-1)^th character and consider all possible permutations, each of these permutations will precede the given permutation. The total number can be computed using the above formula.
Once you compute the number for the first character, fix the first character, and repeat the same with the second character and so on.
Here's the C++ implementation to your question
#include<iostream>
using namespace std;
int fact(int f) {
if (f == 0) return 1;
if (f <= 2) return f;
return (f * fact(f - 1));
}
int solve(string s,int n) {
int ans = 1;
int arr[26] = {0};
int len = n - 1;
for (int i = 0; i < n; i++) {
s[i] = toupper(s[i]);
arr[s[i] - 'A']++;
}
for(int i = 0; i < n; i++) {
int temp = 0;
int x = 1;
char c = s[i];
for(int j = 0; j < c - 'A'; j++) temp += arr[j];
for (int j = 0; j < 26; j++) x = (x * fact(arr[j]));
arr[c - 'A']--;
ans = ans + (temp * ((fact(len)) / x));
len--;
}
return ans;
}
int main() {
int i,n;
string s;
cin>>s;
n=s.size();
cout << solve(s,n);
return 0;
}
Java version of unrank for a String:
public static String unrankperm(String letters, int rank) {
Map<Character, Integer> charCounts = new java.util.HashMap<>();
int permcount = 1;
for(int i = 0; i < letters.length(); i++) {
char x = letters.charAt(i);
int xCount = charCounts.containsKey(x) ? charCounts.get(x) + 1 : 1;
charCounts.put(x, xCount);
permcount = (permcount * (i + 1)) / xCount;
}
// charCounts is the histogram of letters
// permcount is the number of distinct perms of letters
StringBuilder perm = new StringBuilder();
for(int i = 0; i < letters.length(); i++) {
List<Character> sorted = new ArrayList<>(charCounts.keySet());
Collections.sort(sorted);
for(Character x : sorted) {
// suffixcount is the number of distinct perms that begin with x
Integer frequency = charCounts.get(x);
int suffixcount = permcount * frequency / (letters.length() - i);
if (rank <= suffixcount) {
perm.append(x);
permcount = suffixcount;
if(frequency == 1) {
charCounts.remove(x);
} else {
charCounts.put(x, frequency - 1);
}
break;
}
rank -= suffixcount;
}
}
return perm.toString();
}
See also n-th-permutation-algorithm-for-use-in-brute-force-bin-packaging-parallelization.