Igy

 avatar
unknown
plain_text
3 years ago
4.7 kB
4
Indexable
//broj test Caseova
int numOfTestCases = int.Parse(Console.ReadLine());


while (numOfTestCases > 0)
{
    string inputLineTwo = Console.ReadLine();
    string[] inputs = inputLineTwo.Split(' ');

    int N = Convert.ToInt32(inputs[0]);
    int X = Convert.ToInt32(inputs[1]);

    string inputLineThree = Console.ReadLine();
    string[] arrayInputs = inputLineThree.Split(' ');
    int[] arrayOfInt = new int[N];
    
    for(int i = 0; i < arrayOfInt.Length; i++)
    {
        arrayOfInt[i] = int.Parse(arrayInputs[i]);
    }

    int[] output = GetFullInfo(arrayOfInt, X);
    Console.WriteLine($"{output[0]} {output[1]}");

    numOfTestCases--;
}

//vraca niz intova
int[] GetFullInfo(int[] arr, int x)
{
    //na indexu 0 ce se cuvati maksimalan broj ponavljajucih elemenata u nizu
    //na indexu 1 ce se cuvati minimalan broj operacija za taj broj elemenata u nizu
    int[] output = new int[2];

    //niz u koji se spasavaju vrijednosti nakon xor operacije
    int[] arrayAfterOperations = new int[arr.Length];
    for(int i = 0; i < arr.Length; i++)
    {
        arrayAfterOperations[i] = arr[i] ^ x;
        //Console.WriteLine($"nova vrijednost: {arrayAfterOperations[i]}");
    }

    //niz u koji se smjestaju vrijednosti jednakih elemenata iz proslijedjenog niza
    //i iz novog niza nakon xor operacije
    int[] numOfEqual = new int[arr.Length];
    for(int i = 0; i < arr.Length; i++)
    {
        numOfEqual[i] = arr.Count(x => x == arrayAfterOperations[i]);
        //Console.WriteLine($"isti: {arrayAfterOperations.Count(x => x == arr[i])}");
    }

    //najveci broj jednakih elemenata u AfterArray nizu (Max() vraca prvi element u nizu ako ima vise istih)
    int maxNumOfEqualElInAfterArr = numOfEqual.Max();
    //indeks elementa koji se najvise ponavlja
    int indexOfFirstMax = numOfEqual.ToList().IndexOf(maxNumOfEqualElInAfterArr);
   
    //Sada za taj broj koji se najvise ponavlja u AfterArray, njegov indeks je jednak indeksu
    //elementa iz Arr niza koji se najmanje ponavlja u Arr nizu (ovo je bitno zbog broja operacija)
    int maxOfEqualInArr = arr.Count(x => x == arr[indexOfFirstMax]);
    
    //duplikati
    int dupl = 0;
    //grupise sve elemente i trazi da li ima duplikata u Arr nizu
    dupl = arr.GroupBy(x => x)
              .Where(g => g.Count() > 1).Count();
    if(dupl > 0) { 
        //ako ima duplikata, onda se u ovu varijablu spasava najveci broj ponavljanja
        dupl = arr.GroupBy(x => x)
                  .Where(g => g.Count() > 1).Select(y => y.Count()).ToList().Max();
    }
    else
    {
        dupl = 0;
    }

    //ako je broj ponavljanja u arr nizu veci od zbira ponavljanja u modifikovanom AftetArr i proslijedjenom
    //Arr, onda je maksimalan broj elemenata koji se ponavljaju dupl (ostaje isti kao u proslijedjenom stringu)
    //sto znaci da ne treba nijedna operacija da se izvrsi pa je min br operacija 0
    if (dupl > maxNumOfEqualElInAfterArr + maxOfEqualInArr) { 
        output[0] = dupl;
        output[1] = 0;
        return output;
    }
    else { 
    
        output[0] = maxNumOfEqualElInAfterArr + maxOfEqualInArr;
    }
    //Ako nema jednakih elemenata u novom nizu AfterArr onda je i broj operacija 0
    if (maxNumOfEqualElInAfterArr == 0)
    {
        output[1] = maxNumOfEqualElInAfterArr;
        return output;
    }
    
    int numOfMinOperations = 0;
    List<int> minOper = new List<int>();

    //ako ima vise maksimuma u nizu koji pokazuje broj ponavljanja elemenata, treba proci kroz
    //sve te maksimalne elemente da se odredi minimalan broj operacija
    if (numOfEqual.Count(x => x == maxNumOfEqualElInAfterArr) > 1)
    {
        for (int i = 0; i < numOfEqual.Length; i++)
        {
            //kada naidje na maksimalnu cifru
            if(numOfEqual[i] == maxNumOfEqualElInAfterArr)
            {
                //u listu dodaje broj ponavljanja elementa koji se nalazi na indexu (i) 
                //iz arr niza.Taj broj ponavljanja je ujedno i najmanji broj operacija
                //vezan za taj element koji se nalazi na indexu (i)
                minOper.Add(arr.Count(x => x == arr[i]));
            }
        }
    }
    //najmanji broj operacija je maksimalan broj ponavljanja iz proslijedjenog
    //niza arr ukoliko je lista minOper prazna.
    int minOperacije = maxOfEqualInArr;

    //ako lista nije prazna
    if (minOper.Count() > 0) { 
        //onda je min broj operacija jednak najmanjem elementu iz liste minOper
        minOperacije = minOper.Min();
    }

    output[1] = minOperacije;
    
    return output;
}