I am not able to get the logic behind the solution to the problem . I will be very thankful if someone can explain me the working of it.
Solution:
#include <bits/stdc++.h>
using namespace std;
const int N=1509;
int n;
int a[N];
void input(){
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
}
void sol(){
int K=1;
for (int i=1;i<=n;i++)
for (int j=i+1;j<=n;j++)
K^=(a[i]>a[j]);
if (K) printf("YES\n");
else printf("NO\n");
}
int main() {
int test;
scanf("%d",&test);
while (test--){
input();
sol();
}
return 0;
}
I am not able to get how after xoring each permutation, value of 'k' in the end is determining the answer(ie whether it can be arranged in sorting order) ?
When you rotate a block you change the number of inversions by +/- 2 or 0 (work it out on paper, if you don't trust me). So if the number of inversions in the array is odd you will not be able make it sorted with the given operation. You'll end up with the array almost sorted with all but 2 elements in place (1 inversion) and you can't fix that with the given operation.
What the code does is check if the number of inversions is odd by xoring with itself every time it sees an inversion. You can get the same result if you count the inversions up and check inversions % 2 == 0.
Related
I dry ran the code many times but can't find the problem.
#include <stdio.h>
int main()
{
int arr[] = {9,8,5,10,2};
int i, j, k, small;
scanf("%d", &k);
int n=5;
int asc[k];
if(k<n)
{
for(i=0; i<k; i++)
{
small=arr[i];
for(j=i; j<n; j++)
{
if(arr[j]<small)
{
small=arr[j];
}
}
asc[i]=small;
}
printf("%d", asc[k-1]);
}
return 0;
}
output should return kth smallest element. also I created an array "asc" to store the smallest elements in ascending order after each iteration of outer loop.
Output - 2 every time
Expected - when inserted any value(k) less than n, it should return kth smallest element.
What would happen if the smallest element is the last one? That is your case: {9,8,5,10,2}
On each iteration you find the smallest element (2) and assign it to the current element of asc. The result is asc[] = {2, 2, 2} (consists of k equal elements).
Guys I did it with simple sorting. I was trying to do it without using any sorting or any recursion but it seems very difficult if not impossible. Anyways thanks for your help!!
I recently faced this problem in a coding contest:
We have to form a skill squad with members such that no member has more skill than the sum of skills of any two other member in the squad.
Given an array of skills of n members, find the maximum sum of skills of a squad possible with above constraint.
I used a greedy algorithm:
-sort the array;
-use three pointers and choose indices such that the sum of the first two elements (smallest) is lesser than the last (largest element) of the considered subarray.
-Also keep moving the indices to check for all such subarrays and return the maximum sum among them.
But this passed half the cases and others failed. Can someone help me with what I am missing here? Following is my program:
//Author:: Satish Srinivas
#include<bits/stdc++.h>
using namespace std;
int solve(int arr[],int n)
{
sort(arr,arr+n);
int sum[n];
sum[0]=arr[0];
//precompute sums
for(int i=1;i<n;i++)
{
sum[i]=sum[i-1]+arr[i];
}
if(n<=2)
return sum[n-1];
int res=INT_MIN;
for(int i=0;i<=n-3;i++)
{
int min=arr[i]+arr[i+1];
int j=i+1;
while(j<=n-2 && arr[j+1]<=min)
j++;
if(j>i+1)
{
if(i==0)
{
if(res < sum[j]-sum[0])
res=sum[j]-sum[0];
}
else
{
if(res < sum[j]-sum[i-1])
res=sum[j]-sum[i-1];
}
}
}
return res;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
/*
freopen("in.in", "r", stdin);
freopen("out.out", "w", stdout);
*/
int arr1[]={10,4,4,5,4};
int n1=sizeof(arr1)/sizeof(arr1[0]);
cout<<solve(arr1,n1)<<endl;
int arr2[]={25,60,1,5,3,35};
int n2=sizeof(arr2)/sizeof(arr2[0]);
cout<<solve(arr2,n2)<<endl;
return 0;
}
//output:
//13
//120
A few things that look a little wrong:
If n is equal to 2, you return INT_MIN because your for loop never executes
More generally, you seem to consider a team of size 2 as being invalid
When i is equal to 0, you want to compute the score from adding up all numbers from i to j, this is equal to sum[j] but you compute res=sum[j]-sum[0]
As you have sorted the array, you actually don't need to reset j in each iteration (this only matters if you are failing due to a time-out)
Given an array (not sorted) and few range queries. For each query I need to find the number of unique digits within the given range. Here is the naive approach I came up with.
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
int n; scanf("%d",&n); //Size of the array
int a[n+1]; a[0]=0;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int q; scanf("%d",&q); //Number of queries
while(q--)
{
int x,y; scanf("%d %d",&x,&y); //Range of each query
int bit[n+1];
for(int i=0;i<=n;i++)
bit[i]=0;
for(int i=1;i<=n;i++)
{
for(int j=i-1;j>0;j--)
{
bit[i]=a[i];
if(bit[j]==a[i])
{
bit[j]=0;
break;
}
}
}
int cnt=0;
for(int i=x;i<=y;i++)
{
if(bit[i])
cnt++;
}
printf("%d\n",cnt);
}
return 0;
}
What is the most efficient way to do this operation? I think this can be done using Binary Indexed tree but couldn't come up with the solution.
If the number of range queries is small compared to the size of the array, say O(k) vs O(n) where k << n, then:
Put all range endpoints in a balanced binary tree O(klogk)
Make one pass over the array and count unique elements in each subrange. Use a hash table to remember which elements we have already seen. O(n)
Do an in-order traversal between range endpoints for each range query and sum subrange totals. O(k^2) worst case / O(klogk) for reasonable queries.
I have written a code to calculate the minimum number of coins using Greedy algorithm and Dynamic algorithm, but the Dynamic algorithm part doesn't work properly. There is a Null value going to array, I can't find it. Please HELP me. I need a answer as soon as possible.
#include <stdio.h>
int n;
int denom[]={1,2,4,5,20,25};
int coinCounter(int n);
int main(){
printf("Please Enter a Number : ");
scanf("%d",&n);
int coinmin,orin,i;
orin=n;
i=coinmin=0;
for(i=(sizeof(denom)/4)-1;i>=0;i--){
coinmin =coinmin+n/denom[i];
n=n%denom[i];
}
printf("Coin Min By Greedy Algorithm : %d\n",coinmin);
printf("Dynamic Algorithm : %d\n",coinCounter(orin));
return 0;
}
int coinCounter(int n){
int opt[n];
int largest[n];
int i,j,a;
i=j=0;
for(j=1;j<=n;j++){
opt[j]=10000;
//printf("xxn");
for(i=(sizeof(denom)/4)-1;i>=0;i--){
if(denom[i]==j){
opt[j]=1;
largest[j]=j;
}
else if(denom[i]<j){
a=opt[j-denom[i]]+1;
}
if(a<opt[j]){
opt[j]=a;
largest[j]=denom[i];
}
}
}
return opt[n];
}
I edited the Code as following, but the answer is not coming
int coinCounter(int n){
int opt[n];
int largest[n];
int i,j,a;
i=j=0;
for(j=1;j<n;j++){
opt[j]=10000;
printf("xxn");
for(i=(sizeof(denom)/4)-1;i>=0;i--){
if(denom[i]==j){
opt[j]=1;
largest[j]=j;
}
else if(denom[i]<j){
a=opt[j-denom[i]]+1;
}
if(a<opt[j]){
opt[j]=a;
largest[j]=denom[i];
}
}
}
return opt[n-1];
}
hey these are the results I'm Getting
Please Enter a Number : 8
Coin Min By Greedy Algorithm : 3
Dynamic Algorithm : 1
Another answer I'm getting I can't figure out what I'm doing wrong
Please Enter a Number : 71
Coin Min By Greedy Algorithm : 4
Dynamic Algorithm : 3
1
int opt[n]; // not the right way to do dynamic allocation. Use malloc/calloc
int largest[n];
2
for(j=1;j<=n;j++){
^ array is indexed from 0...n-1, index-n is outside array bounds
Don't do this.
int coinCounter(int n){
int opt[n];
int largest[n]; <---- Don't do this. This does not work like you expect it to.
change to
int coinCounter(int n){
int opt[n];
int *largest = malloc(sizeof(int)*n);
Edit:
Another bug with the algorithm
your variable "a" is not initialized and you are using it in if condition.
think of the case when denom[i]>j
your variable "a" would not be initialized
so depending upon what garbage value it has , results will vary
bug is here , but it shows up when you change opt allocation, because that allocation changes the condition. What I want to say is - if (X<Y), depends on both X and Y. Problem is with X, but because you change Y, the condition changes and you get different result
In the problem given here, i have to count total no. of swaps required while sorting an array using insertion sort.
here is my approach
#include <stdio.h>
int main()
{
int t, N, swaps, temp, i, j;
scanf("%d", &t);
while(t--){
scanf("%d", &N);
int arr[N];
swaps = 0;
for(i=0; i<N; ++i){
scanf("%d", &temp);
j=i;
while(j>0 && arr[j-1] > temp){
arr[j] = arr[j-1];
++swaps;
--j;
}
arr[j] = temp;
}
printf("%d\n", swaps);
}
return 0;
}
but, this soln is giving time limit exceeded.
How can i make it more fast?
and, what are the other better solutions of this problem?
this is a standard problem named inversion count
This can be solved using mergesort in O(n*lg(n)). Here is my code for counting the inversions
int a[200001];
long long int count;
void Merge(int p,int q,int r)
{
int n1,n2,i,j,k,li,ri;
n1=q-p+1;
n2=r-q;
int l[n1+1],rt[n2+1];
for(i=0;i<n1;i++)
l[i]=a[p+i];
for(i=0;i<n2;i++)
rt[i]=a[q+1+i];
l[n1]=LONG_MAX;
rt[n2]=LONG_MAX;
li=0;ri=0;
for(i=p;i<=r;i++)
{
if(l[li]<=rt[ri])
a[i]=l[li++];
else
{
a[i]=rt[ri++];
count+=n1-li;
}
}
}
void mergesort(int p,int r)
{
if(p<r)
{
int q=(p+r)/2;
mergesort(p,q);
mergesort(q+1,r);
Merge(p,q,r);
}
}
int main()
{
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
count=0;
mergesort(0,n-1);
printf("%lld\n",count);
}
Basically the problem of inversion count is to find the no. of pairs i and j where j>i such that a[i]>a[j]
To know the idea behind this you should know the basic merge sort algorithm
http://en.wikipedia.org/wiki/Merge_sort
Idea:
Use divide and conquer
divide: size of sequence n to two lists of size n/2
conquer: count recursively two lists
combine: this is a trick part (to do it in linear time)
combine use merge-and-count. Suppose the two lists are A, B. They are already sorted. Produce an output list L from A, B while also counting the number of inversions, (a,b) where a is-in A, b is-in B and a>b.
The idea is similar to "merge" in merge-sort. Merge two sorted lists into one output list, but we also count the inversion.
Everytime a_i is appended to the output, no new inversions are encountered, since a_i is smaller than everything left in list B. If b_j is appended to the output, then it is smaller than all the remaining items in A, we increase the number of count of inversions by the number of elements remaining in A.
This reminds me of a similar problem you may want to look at: http://www.spoj.pl/problems/YODANESS/
In your problem, you can't afford the time to swap everything in case there are many swaps required. (imagine if the input was in reverse order 9,8,7,6.. then you would have to swap everything with everything basically.
I think in your case, each number must be swapped with all the numbers to the left of it that are smaller than it.
I suggest you use a range tree http://en.wikipedia.org/wiki/Range_tree
The great thing about a range tree is each node can know how many nodes are to its left and to its right. You could ask the tree "how many numbers are there greater than 10" very efficiently and that's how many swaps you would have for a 9 say.
The trick is to build the range tree as you move from i=0 to i=N-1. At each point you can query the tree against the ith number before inserting the ith number into the range tree.
good luck!
I did the same code in c++, and it is getting accepted,it is taking time about 4.2 seconds on spoj(http://www.spoj.com/submit/CODESPTB/).
here is the code snippet:
//http://www.spoj.com/problems/CODESPTB/
//mandeep singh #msdeep14
#include<iostream>
using namespace std;
int insertionsort(int arr[], int s)
{
int current,i,j,count=0;
for(i=1;i<s;i++)
{
current=arr[i];
for(j=i-1;j>=0;j--)
{
if(current<arr[j])
{
arr[j+1]=arr[j];
count++;
}
else
break;
}
arr[j+1]=current;
}
return count;
}
int main()
{
int t,n,i,res;
int arr[100000];
cin>>t;
while(t--)
{
cin>>n;
for(i=0;i<n;i++)
{
cin>>arr[i];
}
res=insertionsort(arr,n);
cout<<res<<endl;
}
return 0;
}
#include < stdio.h >
int main() {
int N, swaps, temp[100], i, j;
scanf("%d", & N);
int arr[N];
swaps = 0;
for (i = 0; i < N; i++) {
scanf("%d", & temp[i]);
j = i;
while (j > 0 && arr[j - 1] > temp[i]) {
arr[j] = arr[j - 1];
++swaps;
--j;
}
arr[j] = temp[i];
}
printf("%d", swaps);
return 0;
}