How to create an array with the number of elements that increases with conditions? - c++11

I want to create an array whose number of elements starts with one and is incremented by one when a certain condition is met, but when running I find that when the number of elements increases to 8, it no longer increases, why
#include<iostream>
int main()
{
int a,e,re,n=1;
int arr[n];
scanf("%d%d",&a,&e);
for(int i=0;i<n;i++)
{
if(a%e<0) re=a%e-e;
else re=a%e;
arr[i]=re;
a=(a-re)/e;
if(a!=0) n++;
else break;
}
for(int i=n-1;i>=0;i--)
{
printf("%d",arr[i]);
}
}
This is a base-converted code, when I convert 3 to negative binary, the result is 111, but when I convert 30000 to negative binary, the result is 011110000, but the correct answer should be 11011010101110000, why

Related

Find the missing coordinate of rectangle

Chef has N axis-parallel rectangles in a 2D Cartesian coordinate system. These rectangles may intersect, but it is guaranteed that all their 4N vertices are pairwise distinct.
Unfortunately, Chef lost one vertex, and up until now, none of his fixes have worked (although putting an image of a point on a milk carton might not have been the greatest idea after all…). Therefore, he gave you the task of finding it! You are given the remaining 4N−1 points and you should find the missing one.
Input
The first line of the input contains a single integer T denoting the number of test cases. The description of T test cases follows.
The first line of each test case contains a single integer N.
Then, 4N−1 lines follow. Each of these lines contains two space-separated integers x and y denoting a vertex (x,y) of some rectangle.
Output
For each test case, print a single line containing two space-separated integers X and Y ― the coordinates of the missing point. It can be proved that the missing point can be determined uniquely.
Constraints
T≤100
1≤N≤2⋅105
|x|,|y|≤109
the sum of N over all test cases does not exceed 2⋅105
Example Input
1
2
1 1
1 2
4 6
2 1
9 6
9 3
4 3
Example Output
2 2
Problem link: https://www.codechef.com/problems/PTMSSNG
my approach: I have created a frequency array for x and y coordinates and then calculated the point which is coming odd no. of times.
#include <iostream>
using namespace std;
int main() {
// your code goes here
int t;
cin>>t;
while(t--)
{
long int n;
cin>>n;
long long int a[4*n-1][2];
long long int xm,ym,x,y;
for(int i=0;i<4*n-1;i++)
{
cin>>a[i][0]>>a[i][1];
if(i==0)
{
xm=abs(a[i][0]);
ym=abs(a[i][1]);
}
if(i>0)
{
if(abs(a[i][0])>xm)
{
xm=abs(a[i][0]);
}
if(abs(a[i][1])>ym)
{
ym=abs(a[i][1]);
}
}
}
long long int frqx[xm+1],frqy[ym+1];
for(long long int i=0;i<xm+1;i++)
{
frqx[i]=0;
}
for(long long int j=0;j<ym+1;j++)
{
frqy[j]=0;
}
for(long long int i=0;i<4*n-1;i++)
{
frqx[a[i][0]]+=1;
frqy[a[i][1]]+=1;
}
for(long long int i=0;i<xm+1;i++)
{
if(frqx[i]>0 && frqx[i]%2>0)
{
x=i;
break;
}
}
for(long long int j=0;j<ym+1;j++)
{
if(frqy[j]>0 && frqy[j]%2>0)
{
y=j;
break;
}
}
cout<<x<<" "<<y<<"\n";
}
return 0;
}
My code is showing TLE for inputs <10^6
First of all, your solution is not handling negative x/y correctly. long long int frqx[xm+1],frqy[ym+1] allocated barely enough memory to hold positive values, but not enough to hold negative ones.
It doesn't even matter though, as with the guarantee that abs(x) <= 109, you can just statically allocate a vector of 219 elements, and map both positive and negative coordinates in there.
Second, you are not supposed to buffer the input in a. Not only is this going to overflow the stack, is also entirely unnecessary. Write to the frequency buckets right away, don't buffer.
Same goes for most of these challenges. Don't buffer, always try to process the input directly.
About your buckets, you don't need a long long int. A bool per bucket is enough. You do not care even the least how many coordinates were sorted into the bucket, only whether the number so far was even or not. What you implemented as a separate loop can be substituted by simply toggling a flag while processing the input.
I find the answer of #Ext3h with respect to the errors adequate.
The solution, giving that you came on the odd/even quality of the problem,
can be done more straight-forward.
You need to find the x and y that appear an odd number of times.
In java
int[] missingPoint(int[][] a) {
//int n = (a.length + 1) / 4;
int[] pt = new int[2]; // In C initialize with 0.
for (int i = 0; i < a.length; ++i) {
for (int j = 0; j < 2; ++j) {
pt[j] ^= a[i][j];
}
}
return pt;
}
This uses exclusive-or ^ which is associative and reflexive 0^x=x, x^x=0. (5^7^4^7^5=4.)
For these "search the odd one" one can use this xor-ing.
In effect you do not need to keep the input in an array.

Non repetitive random number generator in c

I want to make a program that will give me 4 random numbers in the range 1 - 20 without any of them being the same. It does give me 4 different random numbers but every couple of tries 2 numbers are the same. I don't want that.
Here's my code:
int main(){
int g;
srand(time(0));
start:;
scanf("%d",&g);
switch(g){
case 1:RNG_4_10();
break;
default:exit(0);
break;
}
goto start;
}
int RNG_4_10(){
int a,n,i,c;
for(c=0;c<10;c++){
printf("\n");
for(i=0;i<4;i++){
a = (rand() % 20 + 1); //give a random value to a;
n = a; //assign n the value of a;
while(a == n){
a = rand() % 20 + 1;
}
printf("%d\t",a);
}
}
}
Also, I know that RNG's have a probability of repeating numbers and in theory they could generate the same number for infinity, but what I don't get is how can I have 2 similar numbers on the same run. I added that while to avoid that. Is this code wrong or my understanding is awful?
Most random number generators will have a probability of repeating values. If they didn't their behaviour would be less random by various measures.
If you want four random values in the range 1-20, then create an array of 20 elements with all those values, and shuffle it with the help of your random number generator. Then pick the first four values.
A common technique to shuffle is (in pseudocode)
/* shuffle an array of n elements */
for (i = n-1; i > 0; --i)
{
swap(array[i], array[gen(n)]); /* zero-based array indexing */
}
where gen(n) returns a suitably random value with values between 0 and n-1, possibly with repetition.

My code for merge sort in C++ using dynamic arrays returning garbage values

Please tell me why this code is giving garbage values
Compiles well, implemented this based on the Cormen algorithm for mergesorting
Basically taking given numbers in a dynamic array. two void functions are taken.One is to merge the two sub arrays via merge sort and the other to recursively split the array to sub arrays
#include<iostream>
using namespace std;
void merge(int *A,int p, int q, int r)// a function to merge two //sub arrays
{
int n1= q-p+1;
int n2=r-q;
int L[n1];
int R[n2];
for (int i=0;i<n1;i++)
{
L[i]=A[p+i];
}
int m=1;
for(int j=0; j<n2 ;j++)
{
R[j]=A[q+m];
m=m+1;
}
int i=0;
int j=0;
for(int k=0;k<r;k++)
{
if (L[i]<=R[j])
{
A[k]=L[i];
i=i+1;
}
else
{
A[k]=R[j];
j=j+1;
}
}
}
void mergesort(int *A,int p,int r)// dividng the sequence to sub arrays
{
if (p<r)
{
int q;
q=(p+r)/2;
mergesort(A,p,q);
mergesort(A,(q+1),r);
merge(A,p,q,r);
}
}
int main()
{
int n;
cout<<"Enter the number of numbers to be sorted by merge sort"<<endl;
cin>>n;
int* a=NULL;
a=new int[n];
int temp;
cout<<"Enter the numbers"<<endl;
for(int i=0;i<n;i++)
{
cin>>temp;
*(a+i)=temp;// inputting the given numbers into a dynamic array
}
cout<<"The given numbers are:"<<endl;
for(int j=0;j<n;j++)
cout<<*(a+j)<<" ";
mergesort(a,0,n-1);
cout<<"The merged sorted numbers are:"<<endl;
for(int s=0;s<n;s++)
cout<<*(a+s)<<" ";
delete [] a;
system("pause");
return 0;
}
You are getting your intervals wrong pretty much everywhere in your code. For example:
Based on your usage in main, mergesort is supposed to sort the sublist of indices [0,n-1].
With this meaning, your recursion in mergesort says in order to sort the indices [p,r-1], you should first sort [p,q-1] then sort [q+1,r-1]: you completely ignore index q.
Similarly, merge is confused: once you fix the typo when coping into L (A[i] should be A[p+i]), it takes [p,q] as one list, and [q,r] as the other list: note you copy entry q twice, and you also copy r when you probably shouldn't be.
To fix your code, you need to straighten out exactly what intervals everything is supposed to be working on. This isn't a hard problem, you just have to bring yourself to write down explicitly exactly what all of your functions and loops and stuff are supposed to be doing.
The typical convention these days is half-open intervals: you should generally think of taking indices [p,q) from a list. ([p,q) is the same as [p,q-1]) Here are several examples of why this is preferred:
The number of entries of [p,r) is simply r-p
A for loop iterating through [p,r) is the usual for(i=p; i<r; ++i) (not <=)
Splitting the interval [p,r) into parts gives you intervals [p,q) and [q,r) -- there is no worry about remembering to add 1 in places.
e.g. merge would normally be designed to take the first list comes from indices [p,q) and the second list from indices [q,r).

Algorithm to match sets with overlapping members

Looking for an efficient algorithm to match sets among a group of sets, ordered by the most overlapping members. 2 identical sets for example are the best match, while no overlapping members are the worst.
So, the algorithm takes input a list of sets and returns matching set pairs ordered by the sets with the most overlapping members.
Would be interested in ideas to do this efficiently. Brute force approach is to try all combinations and sort which obviously is not very performant when the number of sets is very large.
Edit: Use case - Assume a large number of sets already exist. When a new set arrives, the algorithm is run and the output includes matching sets (with at least one element overlap) sorted by the most matching to least (doesn't matter how many items are in the new/incoming set). Hope that clarifies my question.
If you can afford an approximation algorithm with a chance of error, then you should probably consider MinHash.
This algorithm allows estimating the similarity between 2 sets in constant time. For any constructed set, a fixed size signature is computed, and then only the signatures are compared when estimating the similarities. The similarity measure being used is Jaccard distance, which ranges from 0 (disjoint sets) to 1 (identical sets). It is defined as the intersection to union ratio of two given sets.
With this approach, any new set has to be compared against all existing ones (in linear time), and then the results can be merged into the top list (you can use a bounded search tree/heap for this purpose).
Since the number of possible different values is not very large, you get a fairly efficient hashing if you simply set the nth bit in a "large integer" when the nth number is present in your set. You can then look for overlap between sets with a simple bitwise AND followed by a "count set bits" operation. On 64 bit architecture, that means that you can look for the similarity between two numbers (out of 1000 possible values) in about 16 cycles, regardless of the number of values in each cluster. As the cluster gets more sparse, this becomes a less efficient algorithm.
Still - I implemented some of the basic functions you might need in some code that I attach here - not documented but reasonably understandable, I think. In this example I made the numbers small so I can check the result by hand - you might want to change some of the #defines to get larger ranges of values, and obviously you will want some dynamic lists etc to keep up with the growing catalog.
#include <stdio.h>
// biggest number you will come across: want this to be much bigger
#define MAXINT 25
// use the biggest type you have - not int
#define BITSPER (8*sizeof(int))
#define NWORDS (MAXINT/BITSPER + 1)
// max number in a cluster
#define CSIZE 5
typedef struct{
unsigned int num[NWORDS]; // want to use longest type but not for demo
int newmatch;
int rank;
} hmap;
// convert number to binary sequence:
void hashIt(int* t, int n, hmap* h) {
int ii;
for(ii=0;ii<n;ii++) {
int a, b;
a = t[ii]%BITSPER;
b = t[ii]/BITSPER;
h->num[b]|=1<<a;
}
}
// print binary number:
void printBinary(int n) {
unsigned int jj;
jj = 1<<31;
while(jj!=0) {
printf("%c",((n&jj)!=0)?'1':'0');
jj>>=1;
}
printf(" ");
}
// print the array of binary numbers:
void printHash(hmap* h) {
unsigned int ii, jj;
for(ii=0; ii<NWORDS; ii++) {
jj = 1<<31;
printf("0x%08x: ", h->num[ii]);
printBinary(h->num[ii]);
}
//printf("\n");
}
// find the maximum overlap for set m of n
int maxOverlap(hmap* h, int m, int n) {
int ii, jj;
int overlap, maxOverlap = -1;
for(ii = 0; ii<n; ii++) {
if(ii == m) continue; // don't compare with yourself
else {
overlap = 0;
for(jj = 0; jj< NWORDS; jj++) {
// just to see what's going on: take these print statements out
printBinary(h->num[ii]);
printBinary(h->num[m]);
int bc = countBits(h->num[ii] & h->num[m]);
printBinary(h->num[ii] & h->num[m]);
printf("%d bits overlap\n", bc);
overlap += bc;
}
if(overlap > maxOverlap) maxOverlap = overlap;
}
}
return maxOverlap;
}
int countBits (unsigned int b) {
int count;
for (count = 0; b != 0; count++) {
b &= b - 1; // this clears the LSB-most set bit
}
return count;
}
int main(void) {
int cluster[20][CSIZE];
int temp[CSIZE];
int ii,jj;
static hmap H[20]; // make them all 0 initially
for(jj=0; jj<20; jj++){
for(ii=0; ii<CSIZE; ii++) {
temp[ii] = rand()%MAXINT;
}
hashIt(temp, CSIZE, &H[jj]);
}
for(ii=0;ii<20;ii++) {
printHash(&H[ii]);
printf("max overlap: %d\n", maxOverlap(H, ii, 20));
}
}
See if this helps at all...

Running sum maximum item minimization

I am making a physics optimizer, where a critical part is solved by the following CS question.
You are given an array of random signed integers. Their sum is zero. One can make a loop that keeps a running sum as follows:
int running_sum = 0;
int sum_peak = 0;
for( int i = 0; i < size_of_array; i++ )
{
running_sum += int_array[i];
sum_peak = max( sum_peak, abs( running_sum ) );
}
assert( running_sum == 0 );
The task is to minimize the resultant sum_peak by permuting the initial int_array. My thoughts so far: the naive approach takes an exponential amount of time to run. This problem does not seem to be expressed by any NP-C problems I know of. I can't think of any way to represent this problem as a graph problem.
If X is the largest number (by absolute value) in the array, the upper and lower bounds of max_sum are N and N/2, respectively.
EDIT: examples.
{-4, -6, 10}: reorder the list as the following: {-6, 10, -4}, so that the sum_peak is -6.
{1, 1, 1, 1, -4}: reorder the list as the following: { 1, 1, -4, 1, 1 }, so that the sum_peak is +2.
this may be a bogus (if I misunderstood the problem) but sometimes the easiest way is the best one
if the int's are unsigned then there is no help
if there are signed then:
1.input array
1,5,-2,7,-6,4,-10,-3,...
2.separate signed and unsigned valueas and sort by value
+1,+4,+5,+7,...
-2,-3,-6,-10,...
3.reorder original array
this can be done more ways
the easiest one is just even numbers are + and odd ones are -
+1,-2,+4,-3,+5,-6,+7,-10
this is fast but not optimal
still will cut down the peak significantly
another option is:
1.while (sum>=0) add number from +array
2.while (sum< 0) add number from -array
3.when one array is all used then copy the unused rest
do not think you can do better then this
Where did the NP complete come from ???
or I am missing something ???
[edit 1]
also it can be improved to obtain optimal solution like
use smaller from the big unused values to get sum to half size of the max unused value from the opposite array...
also all can be done in-place
[edit 2] some code and testing
//---------------------------------------------------------------------------
void min_sum_peak()
{
const int N=1000;
int in[N],out[N];
int i,s,sp,e,ip0,im0,ip1,im1;
// generate sum=0 random array to in and clear out (for easyier debug)
for (s=0,i=1;i<N;i++)
{
in[i]=Random(1000)-500;
s+=in[i];
out[i]=0;
} in[0]=-s; out[0]=0;
// bubble sort in[]
for (e=1;e;)
for (e=0,i=1;i<N;i++)
if (in[i-1]>in[i])
{ e=in[i-1]; in[i-1]=in[i]; in[i]=e; e=1; }
// fill out[]
#define peak { e=s; if (e<0) e=-e; if (sp<e) sp=e; }
for (int mode=0;mode<3;mode++)
{
// scann for +/- boundary
im0=-1; ip0=N;
im1= 0; ip1=N-1;
for (i=0;i<N;i++)
if (in[i]<0) im0=i;
else { ip0=i; break; }
if (mode==0) // even odd from smaller values (sp = ~2*max)
for (i=0,s=0,sp=0;i<N;)
{
if (im0>=im1){ out[i]=in[im0]; s+=out[i]; im0--; i++; peak; }
if (ip0<=ip1){ out[i]=in[ip0]; s+=out[i]; ip0++; i++; peak; }
}
if (mode==1) // even odd from bigger values (sp = ~max)
for (i=0,s=0,sp=0;i<N;)
{
if (im0>=im1){ out[i]=in[im1]; s+=out[i]; im1++; i++; peak; }
if (ip0<=ip1){ out[i]=in[ip1]; s+=out[i]; ip1--; i++; peak; }
}
if (mode==2) // -half sum to next max value (sp = ~0.5*max for big enough array)
{
for (i=0,s=0,sp=0;;)
{
if (im0<im1) break; // stop if any + or - valueas are exhausted
if (ip0>ip1) break;
if (s>=0)
{
if (+s+s<-in[im1]){ out[i]=in[ip0]; s+=out[i]; ip0++; i++; }
else { out[i]=in[im1]; s+=out[i]; im1++; i++; }
}
else{
if (-s-s<+in[ip1]){ out[i]=in[im0]; s+=out[i]; im0--; i++; }
else { out[i]=in[ip1]; s+=out[i]; ip1--; i++; }
}
peak;
}
for (;im0>=im1;){ out[i]=in[im0]; s+=out[i]; im0--; i++; peak; }
for (;ip0<=ip1;){ out[i]=in[ip0]; s+=out[i]; ip0++; i++; peak; }
}
i=-in[0]; if (i<in[N-1]) i=in[N-1];
// breakpoint here for approach assesment
mode=mode; // used approach
i = i; // abs max value
s = s; // sum
sp=sp; // sum peak
}
#undef peak { e=s; if (e<0) e=-e; if (sp<e) sp=e; }
}
//---------------------------------------------------------------------------
mode 0 - even odd from smaller values sp = ~2*max_abs_value
mode 1 - even odd from bigger values sp = ~max_abs_value
mode 2 - half sum to next max value sp = ~0.5*max_abs_value
for big enough arrays with 'evenly' distributed +/- values is mode 2 the best as expected
but if array is small (for example N=20) then mode 1 is the winner
mode 0 is not good at all

Resources