Schedule round robin matches - algorithm

How to implement a round robin schedule for an array of 4 elements [1,2,3,4]? The result of the algorithm should be able to display, for each element, the list of the players it will face in chronological order:
(1: 4,2,3)
(2: 3,1,4)
(3: 2,4,1)
(4: 1,3,2)
Line 1: 4,2,3 means that the player (1) will face in order the players (4), (2) and (3).
Of the same way, line 2: 3,1,4 indicates that the player (2) will face in order the players (3), (1) and (2).
We have implemented this code but we encounter a bug when we start filling in the name of the player. Do you have any idea about this problem?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NAME_MAX_LENGTH 20
#define NUM_MIN_PLAYERS 2
#define NUM_MAX_PLAYERS 20
enum Style
{
STYLE_COMPACT,
STYLE_TABLE
};
enum Format
{
FORMAT_ID,
FORMAT_NAME
};
struct PlayerList
{
unsigned int num_players;
char name[NUM_MAX_PLAYERS][NAME_MAX_LENGTH + 1];
};
struct Grid
{
unsigned int num_players;
unsigned int day[NUM_MAX_PLAYERS]
[NUM_MAX_PLAYERS];
};
void printList(struct PlayerList *list)
{
for (int i = 0; i < list->num_players; i++)
{
printf("%d:%s\n", i + 1, list->name[i]);
}
}
struct Grid calculer_berger(struct PlayerList *list)
{
struct Grid grid;
// algo pour remplir la grid
grid.num_players = list->num_players;
int i, j;
for (i = 0; i < list->num_players - 1; i++)
{
for (j = 0; j < list->num_players - 1; j++)
{
if (i == j)
{
/* edge cases */
grid.day[i][list->num_players - 1] = ((i + j) + (i + j) / list->num_players) % list->num_players;
grid.day[list->num_players - 1][j] = ((i + j) + (i + j) / list->num_players) % list->num_players;
grid.day[i][j] = 0;
}
else
{
grid.day[i][j] = ((i + j) + (i + j) / list->num_players) % list->num_players;
}
}
}
grid.day[0][list->num_players - 1] = list->num_players - 1;
grid.day[list->num_players - 1][list->num_players - 1] = 0;
grid.day[list->num_players - 1][0] = list->num_players - 1;
return grid;
}
void permuter(struct Grid *grid)
{
int tmp;
for (int i = 0; i < grid->num_players; i++)
{
for (int j = 1; j <= grid->num_players / 2; j++)
{
tmp = grid->day[i][j];
grid->day[i][j] = grid->day[i][grid->num_players - j];
grid->day[i][grid->num_players - j] = tmp;
}
}
}
void print_grid(struct Grid *grid, struct PlayerList *list)
{
for (int i = 0; i < grid->num_players; i++)
{
for (int j = 0; j < grid->num_players; j++)
{
if (j == 0)
{
printf("%d:", grid->day[i][j] + 1);
}
else
{
printf("%d", grid->day[i][j] + 1);
if (j < grid->num_players - 1)
{
printf(",");
}
}
}
printf("\n");
}
}
int main(int argc, char **argv)
{
struct PlayerList playerList;
char nom[NAME_MAX_LENGTH + 1];
int nbCharLu = 0;
while ((nbCharLu = fscanf(stdin, "%s", nom)) != -1)
{
strcpy(playerList.name[playerList.num_players], nom);
playerList.num_players++;
}
struct Grid myGrid = calculer_berger(&playerList);
printList(&playerList);
print_grid(&myGrid, &playerList);
printf("Apres la permut\n");
permuter(&myGrid);
print_grid(&myGrid, &playerList);
return 0;
}

Assuming you are storing the elements in an Integer array and that you would like to just display the results.
Here is one implementation....The code should accommodate "N" values because of the use of "sizeof"....
feel free to customize it further....
#include <stdio.h>
int main() {
int i,j;
int array[] = {1,2,3,4};
for(i = 0; i < sizeof(array)/sizeof(int);++i){
printf("(%d :",array[i]);
for(j = 0; j < sizeof(array)/sizeof(int);++j){
if(j == i)
continue;
printf("%d ",array[j]);
}
printf(")\n");
}
}

#include <stdio.h>
void main() {
int mid;
int num;
int j, temp;
int k = 0;
int num1;
int data[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14};
num = sizeof(data)/sizeof(int);
mid = (sizeof(data)/sizeof(int))/2;
while(k < num - 1){
printf("Round %d ( ",k+1);
num1 = num;
for(int i = 0;i < mid;i++,num1--) /*pairing the competitors in each round*/
printf("%d:%d ",data[i],data[num1-1]);
for(int i = 0,j = num-1; i < num -2;i++,j--){ /* fixing the first competitor and rotating the others clockwise*/
temp = data[j];
data[j] = data[j-1];
data[j-1] = temp;
}
printf(")\n");
k++;
}
}

Related

Runtime error for large inputs for sorting ( quicksort)

This is a very simple program where the user inputs (x,y) coordinates and distance 'd' and the program has to find out the number of unrepeated coordinates from (x,y) to (x+d,y).
For eg: if input for one test case is: 4,9,2 then the unrepeated coordinates are (4,9),(5,9) and (6,9)(x=4,y=9,d=2). I have used a sorting algorithm as mentioned in the question (to keep track of multiple occurrences) however the program shows runtime error for test cases beyond 30. Is there any mistake in the code or is it an issue with my compiler?
For a detailed explanation of question: https://www.hackerearth.com/practice/algorithms/sorting/merge-sort/practice-problems/algorithm/missing-soldiers-december-easy-easy/
#include <stdio.h>
#include <stdlib.h>
int partition(int *arr, int p, int r) {
int x;
x = arr[r];
int tmp;
int i = p - 1;
for (int j = p; j <= r - 1; ++j) {
if (arr[j] <= x) {
i = i + 1;
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
tmp = arr[i + 1];
arr[i + 1] = arr[r];
arr[r] = tmp;
return (i + 1);
}
void quicksort(int *arr, int p, int r) {
int q;
if (p < r) {
q = partition(arr, p, r);
quicksort(arr, p, q - 1);
quicksort(arr, q + 1, r);
}
}
int count(int A[],int ct) {
int cnt = 0;
for (int i = 0; i < ct; ++i) {
if (A[i] != A[i + 1]) {
cnt++;
}
}
return cnt;
}
int main() {
int t;
scanf("%d", &t);
long int tmp, y, d;
int ct = 0;
int i = 0;
int x[1000];
int j = 0;
for (int l = 0; l < t; ++l) {
scanf("%d%d%d", &tmp, &y, &d);
ct = ct + d + 1; //this counts the total no of coordinates for each (x,y,d)
for (int i = 0; i <= d; ++i) {
x[j] = tmp + i; //storing all possible the x and x+d coordinates
j++;
}
}
int cnt;
int p = ct - 1;
quicksort(x, 0, p); //quicksort sorting
for (int l = 0; l < ct; ++l) {
printf("%d ", x[l]); //prints sorted array not necessary to question
}
cnt = count(x, ct); //counts the number of non-repeated vertices
printf("%d\n", cnt);
}
The problem was the bounds of the array int x[1000] is not enough for the data given below.

Code just loads for a second, then closes without doing anything

For some reason, whenever I run this code, it just opens; loads for a sec; then closes without doing anything. Whenever I try to narrow it down to a piece of code, it makes absolutely no sense, like the line int dirX.
#include <iostream>
#include <queue>
using namespace std;
void solve()
{
// ENTER CODE BELOW
struct Loc
{
int x, y;
Loc (int xx=0, int yy=0) : x(xx), y(yy) {}
};
int n=0, currX=1002, currY=1002, dx[]={-1,1,0,0},dy[]={0,0,-1,1}; string str=""; bool isFence[2010][2010]; queue<Loc> q;
int ret=-1;
for (int i = 0; i < 2005; i++) {
for (int j = 0; j < 2005; j++) {
isFence[i][j]=false;
}
}
cin >> n >> str;
isFence[currX][currY]=true;
int dirX, dirY;
for (auto i : str)
{
dirX=0; dirY=0;
if (i=='N') dirX=-1;
else if (i=='S') dirX=1;
else if (i=='W') dirY=-1;
else dirY=1;
for (int j = 0; j < 2; j++) {
currX += dirX;
currY += dirY;
isFence[currX][currY]=true;
}
}
Loc curr; int nx, ny;
for (int i = 0; i < 2005; i++)
{
for (int j = 0; j < 2005; j++)
{
cout << isFence[i][j] << endl;
if (isFence[i][j]) continue;
ret++;
q = std::queue<Loc>();
q.push(Loc(i,j));
isFence[i][j]=true;
while (!q.empty())
{
curr = q.front(); q.pop();
for (int k = 0; k < 4; k++) {
nx = curr.x+dx[k]; ny=curr.y+dy[k];
if (nx >= 0 && nx < 2005 && ny >= 0 && ny<2005 && !isFence[nx][ny]) {
isFence[nx][ny]=true;
q.push(Loc(nx, ny));
}
}
}
}
}
cout << ret;
// ENTER CODE ABOVE
}
int main()
{
solve();
}
Also, the reason I have all my code in the solve() function was because this is an assignment and I have to do it this way.
Sidenote: I wrote this code very quickly, so it's very badly formatted.

how to fastly find array which include some numbers(1~255)?

I want to solve some algorithm problem.
Could you suggest any algorithms working more fast?
*Problem summary
- Find same array of key[200] is same as source array KEY[200]
- Each element of KEY[200] array is random numbers range 1~255
- only 2 file are given.
- You must implement just function find_array() of user_code.cpp
- It is not allowed to edit any other things
- You can use check() function for finding array
- test case is 50, time limit is 10 sec for 50 test case, memory limit is 256MB.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
extern void find_array(unsigned char key[200]);
unsigned char KEY[200];
int check(unsigned char key[200])
{
int pos = 0;
int equal = 0;
for (int c = 0; c < 200; c++)
{
if (key[c] == KEY[c])
pos++;
}
for (int c1 = 0; c1 < 200; c1++)
{
for (int c2 = 0; c2 < 200; c2++)
{
if(key[c1] == KEY[c2])
equal++;
}
}
return pos * 256 + equal;
}
int main()
{
for (int t = 0; t < 1; t++) //test case 50개
{
for (int i = 0; i < 200; i++)
{
KEY[i] = rand() % 255 + 1; //1~255
}
unsigned char key[200] = { 0, };
find_array(key); //you must implement this function
}
return 0;
}
//user_code.cpp
extern int check(unsigned char key[200]);
//you must implement this function
//below is my code take a long time(about 2sec for each case)
void find_array(unsigned char key[200])
{
unsigned char temp[200];
int result, pos, equal;
for (int k = 0; k < 200; k++)
temp[k] = 0;
for (int i = 0; i < 200; i++)
{
for (int val = 1; val <= 255; val++)
{
temp[i] = val;
result = check(temp);
equal = result % 256;
pos = (result - equal) / 256;
if (pos >= 1)
{
key[i] = val;
temp[i] = 0;
break;
}
}
}
}

Why are my MaxHeapify and BuildMaxHeap procedures failing to organise a heap?

In my ansi-c implementation of heap I have two procedures:
void MaxHeapify(Heap * h, int i)
{
int l = Left(i);
int r = Right(i);
int L, tmp;
if(l < h->heapsize && h->data[l] > h->data[i]) L = l;
else L = i;
if(r < h->heapsize && h->data[r] > h->data[L]) L = r;
if(L != i)
{
tmp = h->data[i];
h->data[i] = h->data[L];
h->data[L] = tmp;
MaxHeapify(h, L);
}
}
void BuildMaxHeap(Heap * h)
{
int i;
h->heapsize = h->length;
for(i = h->length / 2; i >= 0; i--)
MaxHeapify(h, i);
}
And main.c
int main(int argc, char *argv[])
{
int i;
Heap h;
int tab[] = {4,1,3,2,16,9,10,14,8,7};
HeapInit(&h, tab, 10);
for(i = 0; i < 10; i++) printf("%d ", h.data[i]);
printf("\n");
BuildMaxHeap(&h);
for(i = 0; i < 10; i++) printf("%d ", h.data[i]);
return 0;
}
I have strange output:
16 14 10 10 8 1 4 2 3 7
I've checked code a few times, but found nothing wrong.
CORRECTED NODE INDEX RETURNING FUNCTIONS:
int Left(int i)
{
return 2*i+1;
}
int Right(int i)
{
return 2*i+2;
}
#JimMischel posted correct answer in comments. It was written basing on pseudocode with indexing from 1 and that confused me. Correct code posted (via edit) in question.

Euler's Totient function permutation

I was doing this problem on SPOJ. www.spoj.com/problems/TIP1.
I have written this code but I am getting time limit exceeded when judged. Can anyone help me with any optimization or a better approach.
if N is a positive integer, then PHI(N) is the number of integers K for which GCD(N, K) = 1 and 1 ≤ K ≤ N. We denote GCD the Greatest Common Divisor. For example, we have PHI(9)=6.
#include<iostream>
#include<vector>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
#define N 10000010
#define MAXN 10000010
int phi[MAXN + 1], prime[MAXN/10], sz=0;
vector<bool> mark(MAXN + 1);
int ans[10000011];
vector<int> a(10);
vector<int> b(10);
bool isprm(long int x)
{
for(int s=0; s<10; s++)
{
a[s]=b[s]=0;
}
long int y=phi[x];
int i=0,j=0;
while(x>0)
{
int rem=x%10;
x=x/10;
a[i]=rem;
i++;
}
while(y>0)
{
int rem=y%10;
y=y/10;
b[j]=rem;
j++;
}
sort(a.begin(), a.end());
sort(b.begin(), b.end());
if(i!=j)
return false;
for(int s=0; s<10; s++)
{
if(a[s]!=b[s])
return false;
}
return true;
}
void precompute_again()
{
for(int i=0; i<=20; ++i)
ans[i]=0;
ans[21]=21;
for(long int i=22; i<10000005; ++i){
bool chk=false;
chk=isprm(i);
if(chk==true)
{
if(i*phi[ans[i-1]]==phi[i]*ans[i-1])
{
ans[i]=i;
}
else
{
if(i*phi[ans[i-1]]>phi[i]*ans[i-1])
{
ans[i]=ans[i-1];
}
else
{
ans[i]=i;
}
}
}
else
{
ans[i]=ans[i-1];
}
}
}
int main()
{
phi[1] = 1;
for (int i = 2; i <= MAXN; i++ ){
if(!mark[i]){
phi[i] = i-1;
prime[sz++]= i;
}
for (int j=0; j<sz && prime[j]*i <= MAXN; j++ ){
mark[prime[j]*i]=1;
if(i%prime[j]==0){
int ll = 0;int xx = i;
while(xx%prime[j]==0)
{
xx/=prime[j];
ll++;
}
int mm = 1;
for(int k=0;k<ll;k++)mm*=prime[j];
phi[i*prime[j]] = phi[xx]*mm*(prime[j]-1);
break;
}
else phi[i*prime[j]] = phi[i]*(prime[j]-1 );
}
}
precompute_again();
int t;
scanf("%d",&t);
while(t--)
{
long int m;
scanf("%ld",&m);
cout<<ans[m]<<endl;
}
return 0;
}
Try to use a variant of Sieve of Eratosthenes.
The following code computes all phi[N] up to MAXN. For MAXN = 1e7 it runs in the blink of an eye.
int i, j;
int * phi = new int [MAXN];
for (i = 1; i < MAXN; i ++)
phi[i] = i;
for (i = 2; i < MAXN; i ++)
{
if (phi[i] != i) continue;
for (j = i; j < MAXN; j += i)
phi[j] = phi[j] / i * (i - 1);
}

Resources