- array median transformation minimum steps
- #include <cstdio>
- #include <iostream>
- using namespace std;
- int bc[1<<15];
- const int M = (1<<15) - 1;
- void setMin(int& ret, int c)
- {
- if(c < ret) ret = c;
- }
- void doit(int n, int mask, int currentSteps, int& currentBest)
- {
- int numMax = bc[mask>>15] + bc[mask&M];
- if(numMax == n) {
- setMin(currentBest, currentSteps);
- return;
- }
- if(currentSteps + 1 >= currentBest)
- return;
- if(currentSteps + 2 >= currentBest)
- {
- if(numMax * 2 >= n) {
- setMin(currentBest, 1 + currentSteps);
- }
- return;
- }
- if(numMax < (1<<currentSteps)) return;
- for(int i=0;i<n;i++)
- {
- int a = 0, b = 0;
- int c = mask;
- for(int j=i;j<n;j++)
- {
- c |= (1<<j);
- if(mask&(1<<j)) b++;
- else a++;
- if(b >= a) {
- doit(n, c, currentSteps + 1, currentBest);
- }
- }
- }
- }
- int v[32];
- void solveCase() {
- int n;
- scanf(" %d", &n);
- int maxElement = 0;
- for(int i=0;i<n;i++) {
- scanf(" %d", v+i);
- if(v[i] > maxElement) maxElement = v[i];
- }
- int mask = 0;
- for(int i=0;i<n;i++) if(v[i] == maxElement) mask |= (1<<i);
- int ret = 0, p = 1;
- while(p < n) {
- ret++;
- p *= 2;
- }
- doit(n, mask, 0, ret);
- printf("%dn",ret);
- }
- main() {
- for(int i=0;i<(1<<15);i++) {
- bc[i] = bc[i>>1] + (i&1);
- }
- int cases;
- scanf(" %d",&cases);
- while(cases--) solveCase();
- }
- [6 1 5 9 3 2 0 7 4 8]
- [6 1 5 9 9 2 0 7 4 8]
- [6 9 9 9 9 2 0 7 4 8]
- [9 9 9 9 9 9 9 9 4 8]
- [9 9 9 9 9 9 9 9 9 9]
- For each group of consecutive maximal elements in original array:
- Mark corresponding element in the matrix and clear other elements
- For each matrix diagonal, starting with one, containing this element:
- For each marked element in this diagonal:
- Retrieve current number of turns from this matrix element
- (use indexes of this matrix element to initialize p1 and p2)
- p2 = end of the group
- p1 = start of the group
- Decrease p1 while it is possible to keep median at maximum value
- (now all values between p1 and p2 are assumed as maximal)
- While p2 < N:
- Check if number of maximal elements in the array is >= N/2
- If this is true, compare current number of turns with the best result
- and update it if necessary
- (additional matrix with number of maximal values between each pair of
- points may be used to count elements to the left of p1 and to the
- right of p2)
- Look at position [p1, p2] in the matrix. Mark it and if it contains
- larger number of turns, update it
- Repeat:
- Increase p1 while it points to maximal value
- Increment p1 (to skip one non-maximum value)
- Increase p2 while it is possible to keep median at maximum value
- while median is not at maximum value