Solution for SPOJ AGGRCOW - c++

I have the folowing problem:
Farmer John has built a new long barn, with N (2 <= N <= 100,000)
stalls. The stalls are located along a straight line at positions
x1,...,xN (0 <= xi <= 1,000,000,000).
His C (2 <= C <= N) cows don't like this barn layout and become
aggressive towards each other once put into a stall. To prevent the
cows from hurting each other, FJ wants to assign the cows to the
stalls, such that the minimum distance between any two of them is as
large as possible. What is the largest minimum distance?
Input
t – the number of test cases, then t test cases follows.
* Line 1: Two space-separated integers: N and C
* Lines 2..N+1: Line i+1 contains an integer stall location, xi
Output
For each test case output one integer: the largest minimum distance.
Example
Input:
1
5 3
1
2
8
4
9
Output:
3 Output details:
FJ can put his 3 cows in the stalls at positions 1, 4 and 8,
resulting in a minimum distance of 3. Submit solution!
My approach was to pick some pair which has a certain gap and check if there are enough elements in the array to satisfy the need of all the cows.
To find these elements,I used binary search.
When I find an element , I reset my left to mid so I can continue based on the number of cows left.
My code:
#include <iostream>
int bsearch(int arr[],int l,int r,int gap , int n,int c){
int stat = 0;
for (int i = 1;i <= c; ++i) {
while(l <= r) {
int mid = (l+r)/2;
int x = n+(i*gap);
if (arr[mid] > x && arr[mid-1] < x) {
l = mid;
++stat;
break;
}
if(arr[mid] < x) {
l = mid + 1;
}
if (arr[mid] > x) {
r = mid - 1;
}
}
}
if (stat == c) {
return 0;
}
else {
return -1;
}
}
int calc(int arr[],int n , int c) {
int max = 0;
for (int i = 0; i < n; ++i) {
for (int j = i+1;j < n; ++j) {
int gap = arr[j] - arr[i];
if (gap > max) {
if (bsearch(arr,j,n-1,gap,arr[j],c) == 0) {
max = gap;
}
}
}
}
return max;
}
using namespace std;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int t , n ,c;
cin >> t;
for(int i = 0 ; i < t; ++i) {
cin >> n >> c;
int arr[n];
for (int z = 0 ; z < n; ++z) {
cin >> arr[z];
}
sort(arr,arr+n);
//Output;
int ans = calc(arr,n,c);
cout << ans;
}
return 0;
}
Problem Page:
https://www.spoj.com/problems/AGGRCOW/

Related

multiples of x in a number

suppose we are given a range from l to r.We are asked to find count of that numbers whose all digits are multiples of x. x can be any number from 1 to 9. For example, take l=20 and r=40 and x=2 then required numbers are 20, 22, 24, 26, 28, 40 as multiples of x are 0,2,4,6,8.
I have written a code for that . It runs for some of the test case. I don't why it is giving wrong answer for most of the test case.
constraints : 1<=l<=r<=10^18.
my code :
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
ll s1(vector<string> &v, ll N)
{
ll i, j, n = v.size(), ans = 0;
string ss = "", s = "";
for (i = 0; i < n; i++)
{
s += v[i];
}
ss = to_string(N);
ll d = ss.length(), f = 0, x = n - 1, y = 1;
for (i = 1; i < d; i++)
{
if (i == 1)
{
ans += x;
y = x;
continue;
}
y = y * n;
ans += y;
}
ll z = 0;
for (j = 0; j < d; j++)
{
f = 0;
for (i = 0; i < s.length(); i++)
{
if (z == 0)
{
z++;
continue;
}
if (s[i] < ss[j])
{
ans += pow(n, d - (j + 1));
z++;
}
else if (s[i] == ss[j])
{
z++;
f = 1;
break;
}
}
if (!f)
{
break;
}
}
ans += f;
return and;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while (t--)
{
ll l, r;
ll k, i, g;
cin >> l >> r >> k;
vector<ll> v1;
ll x = 0;
while (x <= 9)
{
v1.push_back(x);
x = x + k;
}
vector<string> s;
for (i = 0; i < v1.size(); i++)
{
g = v1[i];
char c = g + '0';
string d(1, c);
s.push_back(d);
// cout << D[i] << " ";
}
cout << s1(s, r) - s1(s, l - 1) << '\n';
}
}
Can anyone tell me the better logic for this question?
using dynamic programming we can write a function f(x,d) that gives us the amount of numbers in range [0,x] such that every digit is a multiple of d
dp states: [position in X][is our number prefix == X prefix?]
which will use log10(X) * 2 space
starting state is obviously [0][1]
then we just fill up the dp table, especially easy using recursion where we just check whats the next digit we can add that holds all conditions
So total complexity of such dp function would be O(log10(X) * 2 * 10) or simply O(log N) if we remove constants
then answer is simply f(R,x) - f(L-1,x)
Sample code (C++):
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll dp[22][2]; //[position in X][is our number prefix == X prefix?]
ll do_dp(vector<int>&digits, int k, int pos = 0, bool isEq = true)
{
if(pos >= digits.size())return 1;
if(dp[pos][isEq] != -1)return dp[pos][isEq];
dp[pos][isEq] = 0;
for(int d = 0; d <= (isEq ? digits[pos] : 9); d++) //d is next digit
if(d % k == 0) //multiple of k
dp[pos][isEq] += do_dp(digits, k, pos+1, isEq && d == digits[pos]);
return dp[pos][isEq];
}
ll solve(ll x, int k)
{
vector<int>digits;
while(x > 0){
digits.push_back(x%10);
x/=10;
}
reverse(digits.begin(),digits.end());
memset(dp, -1, sizeof dp);
return do_dp(digits, k);
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
ll t,l,r,k;
cin>>t;
while(t--)
{
cin>>l>>r>>k;
cout<<solve(r,k) - solve(l-1,k)<<"\n";
}
}

Check whether all the pairs in an array are divisible by k

Given an array of integers and a number k, write a function that returns true if given array can be divided into pairs such that sum of every pair is divisible by k.
This code is producing correct results for all test cases except one I cannot find the glitch in it.
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
int k;
cin >> k;
int flag[n] = {0};
int p = 0;
int q = 0;
if (n % 2 != 0) {
cout << "False" << endl;
} else {
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if ((arr[i] + arr[j]) % k == 0 && flag[j] == 0) {
p = 1;
flag[j] = 1;
}
}
if (p == 0) {
q = 1;
cout << "False" << endl;
break;
}
}
if (q == 0) {
cout << "True" << endl;
}
}
}
return 0;
}
One of the big sources of bugs in code is messy code. So how do we clean up code? We modularize it. This means breaking up the code so that each portion of the code does one job well. Let's see what that looks like.
Function to check if something is divisible by k:
bool isDivisible(int number, int divisor) {
return number % divisor == 0;
}
Function to check all pairs:
The logic is as follows:
Take the first number in the list; call in n0.
For every remaining number n1, check if that plus the first number is divisible by k
When we find n1 such that n0 + n1 is divisible by k,
a. If the remaining numbers left over can also be split into divisible pairs, return true
b. Otherwise, continue searching
4.If we've searched through all the numbers, return false.
bool pairsDivisible(int* nums, int count, int k) {
if(count == 0) return true;
if(count % 2 != 0) return false; // count must be even
// 1.
int n0 = nums[0];
// 2.
for(int i = 1; i < count; i++) {
int n1 = nums[i];
// 3.
if(isDivisible(n0 + n1, k)) {
// Move the ith number so it's now nums[1]
std::swap(nums[1], nums[i]);
if(pairsDivisible(nums + 2, count - 2, k)) {
return true; // 3.a
} else {
// Reset the array
std::swap(nums[1], nums[i]);
}
}
}
return false;
}

Sorting by multiple attributes

my task is
1) By the quantity of solved tasks in descending order
2) When the quantities of solved tasks are equal – by the penalty time in ascending order
3) When both quantities of solved tasks and penalty times are equal – by the indices of teams in ascending order.
input file gonna be like this:
The first line contains a natural number n (1 ≤ n≤105) – the quantity of teams participating in the contest.
The next n lines contain two numbers S – the quantity of solved tasks (0 ≤ S ≤ 100) and the penalty time T (1 ≤ T ≤ 1000000) of the ith team.
Example:
6
3 50
5 720
1 7
0 0
8 500
8 500
so output file will be:
5 6 2 1 3 4
#include <iostream>
using namespace std;
void swap(int *xp, int *yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
void printArray(int A[],int B[], int size)
{
int i,xx;
for (i = size-1; i >= 0; i--) {
for (int x = 0; x < size; x++) {
if (A[i] == B[x]) {
cout << x+1 << " ";
//break;
}
}
}
}
int main()
{
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int qarray, largest;
cin >> qarray;
int *task = new int[qarray];
int *newtask = new int[qarray];
int *time = new int[qarray];
for (int i = 0; i < qarray; i++)
{
cin >> task[i];
cin >> time[i];
}
for (int i = 0; i <= qarray - 1; i++) {
newtask[i] = task[i];
}
int i, j;
for (i = 0; i < qarray - 1; i++) {
// Last i elements are already in place
for (j = 0; j < qarray - i - 1; j++) {
if (task[j] > task[j + 1]) {
swap(&task[j], &task[j + 1]);
}
}
}
printArray(task, newtask,qarray);
return 0;
}
In short I'm tottaly stucked
Standard library solution (you can replace std::sort with your own sort function):
#include <iostream>
#include <vector>
#include <algorithm>
struct Team
{
std::uint32_t number;
std::uint32_t quantity;
std::uint32_t penalty;
bool operator < (const Team& other) const
{
bool isEqQuantity = quantity == other.quantity;
bool isEqPenalty = penalty == other.penalty;
return quantity > other.quantity
|| (isEqQuantity && penalty < other.penalty)
|| (isEqQuantity && isEqPenalty && number < other.number);
}
};
int main()
{
std::vector<Team> teams;
//Read teams from file
//....
//Or use other sort
std::sort(teams.begin(), teams.end(), [](const Team& t1, const Team& t2)
{
return t1 < t2;
});
for (auto& t : teams)
{
std::cout << t.number << " ";
}
return 0;
}

Find Maximum Strength given number of elements to be skipped on left and right.Please Tell me why my code gives wrong output for certain test cases?

Given an array "s" of "n" items, you have for each item an left value "L[i]" and right value "R[i]" and its strength "S[i]",if you pick an element you can not pick L[i] elements on immediate left of it and R[i] on immediate right of it, find the maximum strength possible.
Example input:
5 //n
1 3 7 3 7 //strength
0 0 2 2 2 //Left Value
3 0 1 0 0 //Right Value
Output:
10
Code:
#include < bits / stdc++.h >
using namespace std;
unsigned long int getMax(int n, int * s, int * l, int * r) {
unsigned long int dyn[n + 1] = {};
dyn[1] = s[1];
for (int i = 2; i <= n; i++) {
dyn[i] = dyn[i - 1];
unsigned long int onInc = s[i];
int left = i - l[i] - 1;
if (left >= 1) {
unsigned int k = left;
while ((k > 0) && ((r[k] + k) >= i)) {
k--;
}
if (k != 0) {
if ((dyn[k] + s[i]) > dyn[i]) {
onInc = dyn[k] + s[i];
}
}
}
dyn[i] = (dyn[i] > onInc) ? dyn[i] : onInc;
}
return dyn[n];
}
int main() {
int n;
cin >> n;
int s[n + 1] = {}, l[n + 1] = {}, r[n + 1] = {};
for (int i = 1; i <= n; i++) {
cin >> s[i];
}
for (int i = 1; i <= n; i++) {
cin >> l[i];
}
for (int i = 1; i <= n; i++) {
cin >> r[i];
}
cout << getMax(n, s, l, r) << endl;
return 0;
}
Problem in your approach:
In your DP table, the information you are storing is about maximum possible so far. The information regarding whether the ith index has been considered is lost. You can consider taking strength at current index to extend previous indices only if any of the previously seen indices is either not in range or it is in range and has not been considered.
Solution:
Reconfigure your DP recurrence. Let DP[i] denote the maximum answer if ith index was considered. Now you will only need to extend those that satisfy range condition. The answer would be maximum value of all DP indices.
Code:
vector<long> DP(n,0);
DP[0]=strength[0]; // base condition
for(int i = 1; i < n ; i++){
DP[i] = strength[i];
for(int j = 0; j < i ; j++){
if(j >= (i-l[i]) || i <= (j+r[j])){ // can't extend
}
else{
DP[i]=max(DP[i],strength[i]+DP[j]); // extend to maximize result
}
}
}
long ans=*max_element(DP.begin(),DP.end());
Time Complexity: O(n^2)
Possible Optimizations:
There are better ways to calculate maximum values which you might want to look into. You can start by looking into Segment tree and Binary Indexed Trees.

Dynamic programming selecting tuples(size T) of nos with each not greater than k and sum S

Guys this is the question
In a tournament, N players play against each other exactly once. Each game results in either of the player winning. There are no ties. You have given a scorecard containing the scores of each player at the end of the tournament. The score of a player is the total number of games the player won in the tournament. However, the scores of some players might have been erased from the scorecard. How many possible scorecards are consistent with the input scorecard?
Input:
The first line contains the number of cases T. T cases follow. Each case contains the number N on the first line followed by N numbers on the second line. The ith number denotes s_i, the score of the ith player. If the score of the ith player has been erased, it is represented by -1.
Output:
Output T lines, containing the answer for each case. Output each result modulo 1000000007.
I have reduced it to the above form of the question but it is failing on large inputs.
This is starting to give me headaches.Any help will be appreciated. I have the following code..am i missing something any corner cases.
#include<stdio.h>
long long solutionMatrix[781][41];
long long
noOfWays (int gamesUndecided, int inHowMany, int noOfPlayers)
{
if (inHowMany > 0 && gamesUndecided >= 0)
{
int i;
long long result;
for (i = noOfPlayers - 1, result = 0; i >= 0; i--)
{
if((gamesUndecided-i)>=0)
{
if (solutionMatrix[gamesUndecided - i][inHowMany - 1] == -1)
solutionMatrix[gamesUndecided - i][inHowMany - 1] = noOfWays (gamesUndecided - i, inHowMany - 1, noOfPlayers);
result += solutionMatrix[gamesUndecided - i][inHowMany - 1];
result %=1000000007L;
}
}
return result%1000000007L;
}
else
return (inHowMany == 0 && gamesUndecided == 0) ? 1 : 0;
}
long long
possibleCards (int score[], int noOfPlayers)
{
int i;
int maxGames = (noOfPlayers * (noOfPlayers - 1)) / 2;
int sumOfGames = 0, unDecided = 0;
for (i = 0; i < noOfPlayers; i++)
{
if (score[i] != -1)
{
if (score[i] >= 0 && score[i] <= noOfPlayers - 1)
{
sumOfGames += score[i];
}
else
return 0;
}
else
unDecided++;
}
if (sumOfGames > maxGames || (unDecided==0 && sumOfGames < maxGames))
return 0;
if (sumOfGames==maxGames && unDecided==0)
return 1;
else
{
int j;
for (i = 0; i < 781; i++)
for (j = 0; j < 41; j++)
solutionMatrix[i][j] = -1;
return noOfWays (maxGames - sumOfGames, unDecided, noOfPlayers)%1000000007L;
}
}
int
main ()
{
int noOfTestCases;
int score[41];
printf("%u\n",0xffffffff);
scanf ("%d", &noOfTestCases);
for (; noOfTestCases > 0; noOfTestCases--)
{
int noOfPlayers;
scanf ("%d", &noOfPlayers);
int i;
for (i = 0; i < noOfPlayers; i++)
{
scanf ("%d", score + i);
}
printf ("%lld\n", possibleCards (score, noOfPlayers));
}
return 0;
}