This is the problem statement:
This is a two player game. Initially there are n integer numbers in an array and players A and B get chance to take them alternatively. Each player can take one or more numbers from the left or right end of the array but cannot take from both ends at a time. He can take as many consecutive numbers as he wants during his time. The game ends when all numbers are taken from the array by the players. The point of each player is calculated by the summation of the numbers, which he has taken. Each player tries to achieve more points from other. If both players play optimally and player A starts the game then how much more point can player A get than player B?
Input
The input consists of a number of cases. Each case starts with a line specifying the integer n (0 < n ≤100), the number of elements in the array. After that, n numbers are given for the game. Input is terminated by a line where n=0.
Output
For each test case, print a number, which represents the maximum difference that the first player obtained after playing this game optimally.
Sample Input Output for Sample Input
4
4 -10 -20 7 7
4
1 2 3 4 10
5
4 -10 -20 7 19 12
0
This is the solution of this problem.
#include<stdio.h>
#include<stdlib.h>
#define maxn 103
//typedef long long bg;
typedef long bg;
bg Table[maxn][maxn];
bg Seq[maxn];
bool Flag[maxn][maxn];
bg N;
bg Sum(int l, int r) {
int i, sum = 0;
for (i = l; i <= r; i++)
sum += Seq[i];
return sum;
}
bg Recur(int L, int R) {
bg max, i, d, k;
if (L == R)
return Seq[L];
if (Flag[L][R])
return Table[L][R];
max = Sum(L, R);
d = Seq[L];
for (i = L + 1; i <= R; i++) {
k = Recur(i, R);
if ((d - k) > max)
max = d - k;
d += Seq[i];
}
d = Seq[R];
for (i = R - 1; i >= L; i--) {
k = Recur(L, i);
if ((d - k) > max)
max = d - k;
d += Seq[i];
}
Flag[L][R] = true;
Table[L][R] = max;
return max;
}
void Cal() {
bg max, i, d, k;
max = Sum(1, N);
d = Seq[1];
for (i = 2; i <= N; i++) {
k = Recur(i, N);
if ((d - k) > max)
max = d - k;
d += Seq[i];
}
d = Seq[N];
for (i = N - 1; i >= 1; i--) {
k = Recur(1, i);
if ((d - k) > max)
max = d - k;
d += Seq[i];
}
printf("%ld\n", max);
}
void Reset() {
for (int i = 1; i <= 100; i++) {
for (int j = 1; j <= 100; j++)
Flag[i][j] = false;
}
}
int main() {
//freopen("in.txt", "r", stdin);
int i;
while (scanf("%ld", &N) && N) {
for (i = 1; i <= N; i++)
scanf("%ld", &Seq[i]);
Cal();
Reset();
}
return 0;
}
I did debug it but found it difficult to understand the solution.
Can anyone explain the code or the solution of this problem. Or can anyone post code to solve this problem with dynamic programming not recursion?
The state here is Table[left][right] which represents the best solution if you have a sequence that includes the elements from left to right inclusive. At each step every possible move is tried - take N elements from the left or N elements from the right, where N is between 1 and right - left.
Example:
4 -10 -20 7
Take from the left:
Table[1][4] = max(sum(1, 1) - Table[2][4], sum(1, 2) - Table[3][4],
sum(1, 3) - Table[4][4], sum(1, 4)).
Take from the right:
Table[1][4] = max(sum(4, 4) - Table[1][3], sum(3, 4) - Table[1][2],
sum(2, 4) - Table[1][1], sum(1, 4)).
sum(L, R) is the sum of array numbers between L and R. I am subtracting because of the next opponent turn.
Related
I was writing an integer to roman numeral converter. This time, a proper one.
Trying to solve the problem of printing the 900s, 90s and 9s; I wrote a for loop (lasts only one loop since it's purpose was to prevent printing CMCMCMCM instead of CM) inside the while loop. But for the variable of the for loop, I used the same "n" as the "n" in the while loop without noticing.
Ran it, worked fine; then noticed the supposed error. Swapped it out with "A", inserted "A" into int cd, cl,..... list. AAAaaand the result was the jumble of completely off the rail numbers.
I don't understand how the code can work properly with a reused loop variable, but can't work with a new one.
#include<stdio.h>
int main()
{
int num, m, c, d, l, x, v, i, n, cm, cd;
printf("Enter Number: ");
scanf_s("%d", &num);
m = num / 1000;
d = (num % 1000) / 500;
c = (num % 500) / 100;
l = (num % 100) / 50;
x = (num % 50) / 10;
v = (num % 10) / 5;
i = (num % 5);
n = m + d + c + l + x + v + i;
while (n > 0)
{
{
for (m; m > 0; m--)
{
printf("M");
}
}
{
for (n=1; n>0; n--)
{
if (num%1000>=900)
{
printf("CM");
d = d - 1;
c = c - 4;
num = num - 900;
}
}
}
{
for (d; d > 0; d--)
printf("D");
}
{
for (n = 1; n > 0; n--)
{
if (num % 500 >= 400)
{
printf("CD");
c = c - 4;
}
}
}
{
for (c; c > 0; c--)
printf("C");
}
{
for (l; l > 0; l--)
printf("L");
}
{
for (x; x > 0; x--)
printf("X");
}
{
for (v; v > 0; v--)
printf("V");
}
{
for (i; i > 0; i--)
printf("I");
}
n--;
}
return 0;
}
Keep in mind, the for loops for the 900, 400 and so on are not completed as I noticed this after writing the 900 single loop.
First, you calculate the quantity of each different letter in the output. Then you have a while loop running with n decreasing to 0, i.e. the body of the loop runs n times. Inside the loop, you have a series of for loops, one for each different letter. If you leave out the for loops that use n, you're doing this:
Calculate the number of each letter in the output: m, d, c, etc. as well as n which is the total number of letters (in additive notation).
Repeat n times:
Print M, m times.
Print D, d times.
etc.
The result is that without the inner loops that modify n, you're printing the result many times over.
A correct algorithm for printing roman numerals in additive notation (4 is IIII, etc.) is:
Calculate m, d, c, etc.
Print M, m times.
Print D, d times.
etc.
Without the for loops that modify n, you're repeating the correct algorithm n times:
while (n > 0) {
… /* code that doesn't modify n and prints the desired output */
n--;
}
With the for loops that modify n, you're setting n to 0 inside the body of the while loop, so n-- at the end of the loop body sets n to -1, and the while loop terminates after the first iteration.
while (n > 0) {
… /* some code */
for (n = 1; n > 0; n--) {
… /* more core */
}
/* On exit of this for loop, the value of n is 0. */
… /* more code that doesn't modify n */
n--;
}
The fix is simple: remove the while loop, since you always want to execute its body exactly once. Remove the calculation of the total number of letters to print: it isn't needed. Your for loops using n execute their body exactly once, too, so they're useless as well. This is the result (I've made the indentation uniform and removed useless braces, but otherwise I didn't seek to improve the program):
#include<stdio.h>
int main()
{
int num, m, c, d, l, x, v, i, cm, cd;
printf("Enter Number: ");
scanf("%d", &num);
m = num / 1000;
d = (num % 1000) / 500;
c = (num % 500) / 100;
l = (num % 100) / 50;
x = (num % 50) / 10;
v = (num % 10) / 5;
i = (num % 5);
for (m; m > 0; m--)
{
printf("M");
}
if (num%1000>=900)
{
printf("CM");
d = d - 1;
c = c - 4;
num = num - 900;
}
for (d; d > 0; d--)
printf("D");
if (num % 500 >= 400)
{
printf("CD");
c = c - 4;
}
for (c; c > 0; c--)
printf("C");
for (l; l > 0; l--)
printf("L");
for (x; x > 0; x--)
printf("X");
for (v; v > 0; v--)
printf("V");
for (i; i > 0; i--)
printf("I");
return 0;
}
This is a C program to find the next greater number with the same digits. This program is working for all given test cases except one. When the input is 472, the expected output is 724. But my output is 247. Can anyone please help me to find the error?
logic I tried to solve this is :
Traverse the given number from rightmost digit, keep traversing till you find a digit which is smaller than the previously traversed digit. For example, if the input number is 534976, we stop at 4 because 4 is smaller than next digit 9. If we do not find such a digit, then output is Not Possible.
Now search the right side of above found digit ‘d’ for the smallest digit greater than ‘d’. For 534976, the right side of 4 contains 976. The smallest digit greater than 4 is 6.
Swap the above found two digits, we get 536974 in above example.
Now sort all digits from position next to ‘d’ to the end of number. The number that we get after sorting is the output. For above example, we sort digits in bold 536974. We get 536479 which is the next greater number for input 534976.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
int main() {
int N, dig[100], i = 0,j, temp, t, s, k, l, min, temp1;
scanf("%d", &N);
while (N > 0) {
dig[i] = N % 10;
i++;
N = N / 10;
}
for (j = 0; j <= i; j++) {
if (dig[j] > dig[j + 1]) {
s = j;
break;
}
}
min = dig[s];
//printf("%d ", min);
for (k = s; k >= 0; k--) {
if (dig[k] <= min) {
min = dig[k];
t = k;
}
}
//printf("%d ", t);
temp = dig[t];
dig[t] = dig[s + 1];
dig[s + 1] = temp;
for (k = 0; k <= s; k++) {
for (l = k + 1; l <= s; l++) {
if (dig[k] < dig[l]) {
temp1 = dig[k];
dig[k] = dig[l];
dig[l] = temp1;
}
}
}
for (k = i - 1; k >= 0; k--) {
printf("%d", dig[k]);
}
}
Your algorithm seems correct, but the loops are incorrect. Some index boundaries are off by one and the comparisons with <= are incorrect. Storing the digits by increasing powers of 10, while more practical is counter-intuitive and complicates the translation of the algorithm into code.
Here is a corrected version, that outputs all greater numbers. You can easily check the output by piping through sort -c to verify order and wc -l to verify that all combinations have been found (there should be at most n! - 1 greater numbers for a number with n digits).
#include <stdio.h>
int main() {
int N, dig[100], i, j, s, t, k, l, temp;
if (scanf("%d", &N) != 1 || N < 0)
return 1;
for (;;) {
for (i = j = 100; N > 0;) {
dig[--i] = N % 10;
N = N / 10;
}
for (s = j - 2; s >= i; s--) {
if (dig[s] < dig[s + 1]) {
break;
}
}
if (s < i) {
/* no greater number with the same digits */
break;
}
t = s + 1;
for (k = t + 1; k < j; k++) {
if (dig[k] < dig[t] && dig[k] > dig[s]) {
t = k;
}
}
temp = dig[t];
dig[t] = dig[s];
dig[s] = temp;
for (k = s + 1; k < j; k++) {
for (l = k + 1; l < j; l++) {
if (dig[k] > dig[l]) {
temp = dig[k];
dig[k] = dig[l];
dig[l] = temp;
}
}
}
N = 0;
for (k = i; k < j; k++) {
N = N * 10 + dig[k];
printf("%d", dig[k]);
}
printf("\n");
}
return 0;
}
Input: 472
Output:
724
742
Intro to problem
You are given a tree. If we select 2 distinct nodes uniformly at random, what's the probability that the distance between these 2 nodes is a prime number?
Input
The first line contains a number N: the number of nodes in this tree.
The following N-1 lines contain pairs a[i] and b[i], which means there is an edge with length 1 between a[i] and b[i].
Output
Output a real number denote the probability we want.
You'll get accept if the difference between your answer and standard answer is no more than 10^-6.
#include<stdio.h>
#include<math.h>
int checkprime(int d);
int fact(int m);
void main()
{
int N, i, j, f, p = 0, t, d, x, y, z;
float result;
int a[49999], b[49999];
printf("Enter the number of nodes\n");
scanf("%d", &N);
printf("\n");
for (i = 0; i < N - 1; i++)
{
scanf("%d\t%d", &a[i], &b[i]);//Inputting the nodes
}
for (i = 0; i < N - 1; i++)
{
for (j = i; j < N - 1; j++)
{
d = b[j] - a[i];//Taking distance between nodes
f = checkprime(d);//Checking if it is prime
if (f == 1)
{
p = p + 1;//If found prime,then increasing the number of
//possibilities
}
}
}
x = fact(N);
y = fact(2);
z = fact(N - 2);
y = y * z;
t = x / y;//finding C(N,2).Combination of number of nodes and pair of 2
result = p / t;//finding probability
printf("\n\n%f", result);
}
int checkprime(int d)//function to check prime
{
int k, flag = 1;
for (k = 2; k < d / 2; k++)
{
if (d % k == 0)
{
flag = 0;
}
}
return flag;
}
int fact(int m)//function to calculate factorial
{
int k, r = 1;
for (k = m; k > 1; k--)
{
r = r * k;
}
return r;
}
In Question, When an array X of size n and a degree k are input,
Write a program that calculates the k-th moving average of array X.
The kth-order moving average of the array X consisting of primitive data values is the average of the last k elements up to the i-th point of X.
That is, A [i] = (X [i-k + 1] + X [i-k + 2] + ... + X [i]) / k.
If the number of the preceding element (including itself) is smaller than k,
Calculate as an average.
For example, if array X is as follows and k is 3, X = 1 3 2 10 6 8
The third moving average is as follows.
A = 1 2 2 5 6 8 A [1] = (1 + 3) / 2, A [2] = (1 + 3 + 2) / 3
However, the program must have the execution time of O (n), not O (nk).
Round off the decimal point in the average calculation and obtain it as an integer.
For exact rounding, do not use% .f, but round it using the int property.
int main()
{
int i, n1, k;
int *array1;
scanf("%d", &n1);
array1 = (int *)malloc(sizeof(int)*n1);
scanf("%d", &k);
for (i = 0; i < n1; i++)
{
scanf("%d", &array1[i]);
}
double tmp = 0;
for (int i = 0; i < n1; i++)
{
tmp += array1[i];
if (i >= k)
{
tmp -= array1[i - k];
}
if (i >= k - 1)
{
double average = tmp / k;
printf("%2lld ", llrint(average));
}
return 0;
}
The program does not work because the problem is not understood.
I would like to know how to solve it.
add) Thank you for answer but the output required by the problem is as follows.
Input : 9 4 (n = 9, k = 3)
2 7 4 5 6 8 2 8 13
Output : 2 5 4 5 6 6 5 6 8
After Modifying your code
int main()
{
int i, n1, k;
int *array1, *array2;
scanf("%d", &n1);
array1 = (int *)malloc(sizeof(int)*n1);
scanf("%d", &k);
for (i = 0; i < n1; i++)
{
scanf("%d", &array1[i]);
}
double tmp = 0;
for (int i = 0; i < n1; i++)
{
tmp += array1[i];
// now tmp contains exactly k + 1 elements sum
// so subtract elements outside of k sized window(leftmost element)
if(i >= k) {
tmp -= array1[i - k];
}
if(i >= k - 1) {
double average = tmp / k;
printf("%lf\n", average);
}
}
return 0;
}
basically what i was trying to do is insert an integer k that represents the number of divisors and then finding all the numbers that have k divisors from 1-100000
#include <stdio.h>
int main(void)
{
int k, x = 1, y = 100000, divisor, count;
printf("Enter the target number of divisors:\n");
scanf("%d", &k);
for (divisor = 0; divisor <= 1; divisor++)
if (x % divisor == 0 && y % divisor == 0)
count++;
printf("There are %d numbers between 1 and 100000 inclusive which have exactly %d divisors\n", k, divisor);
return 0;
}
However I can't seem to be able to do it, please do help me as I'm fairly new to the programming scene and haven't found an answer elsewhere.
There is a theorem that states if you have the canonical representation of an integer being a1b1 * a2b2 ... anbn then the number of divisors of this integer is (b1 + 1) * (b2 + 1) ... (bn + 1).
Now that you have this theorem, you can modify slightly Eratosthenes's sieve to get all integers up to 100 000 in canonical form.
Here is some code that does what I mean by modified erathosthenes's sieve.
const int size = 100000;
int devs[size + 1];
void compute_devs() {
for (int i = 0; i < size + 1; ++i) {
devs[i] = (i%2 == 0) ? 2 : 1;
}
int o = sqrt(size);
for (int i = 3; i <= size; i += 2) {
if (devs[i] != 1) {
continue;
}
devs[i] = i;
if (i <= o) {
for (int j = i * i; j < size; j += 2 * i) {
devs[j] = i;
}
}
}
}
After calling compute_devs the value of devs will store the value of the greatest prime divisor of each number up to size. I will leave the rest of the task to you, but having this array it becomes pretty straight forward.