[Конфигурация] Codeforces 1276C / 1278E Прекрасный прямоугольник

С учетом эффекта

Мы называем матрицей красиво, тогда и только тогда, когда два из того же числа, что не существует в том же столбце или матрицы в том же ряду.

Учитывая \ (п \) число, прошу вас , чтобы выбрать , как много чисел , чтобы дать им возможность составить красивый прямоугольник.

Следует отметить, что настоящее название номер выбранного выходного требуемого количества и состава конкретных программ и размера прямоугольника.

\ (П \ 4 \ Leq раз 10 ^ 5 \)

решение проблемы

Подумайте, в течение нескольких дней, наконец, понял это, я на самом деле было слишком много еды ...

Прежде всего, можно предположить , для \ (х \) прямоугольные линии (так что число столбцов больше или равно число строк), если имело место несколько больше , чем \ (х \) раз, и это число невозможно заполнить все прямоугольника и вы можете заполнить только \ (X \) а, т.е. наклонно для заполнения, нажмите на диаграмму последовательности.

Затем мы используем время обслуживания карты каждый появляется номер, нажмите число вхождений убывания заполнить число, такое же количество наполнения вместе. Почему число Yaoan нисходящее появляется, чтобы заполнить его? Если вы просто заполнить его, он будет взломать этот набор данных.

7
8 5 10 4 10 8 3

Мой ответ

6
2 3
3 5 8
10 4 8

Правильный ответ

6
2 3
8 10 3
4 8 10

Хотя открытие помещается под углом, чтобы заполнить, но даже перечислены в том же два 8. Это может быть показано количеством вхождений убывания заполнить номер, он не будет иметь места.

Тогда мы должны сначала определить , сколько строк этого прямоугольника, от \ (1 \ сим \ SQRT п \) провел несколько штук , чтобы пойти, если предположить , что число строк в текущую нумерацию \ (Row \) , то для каждого числа, самые мы берем \ (строки \) виды, можно рассчитать количество числа общей сложности мы можем взять на себя префикс и + двудольный \ (НСТ \) , то мы можем вычислить количество строк \ (Col = \ влево \ lfloor \ гидроразрыва {Cnt} строка} {\ право \ rfloor \ Времена строки \) , но \ (ИСП \) не меньше , чем \ (\) строки , в противном случае не соответствует числу столбцов равно числу строк больше , чем наши определено ранее. Можно доказать существование определенного способа заполнения, который может заполнить \ (\ Его раза Col \) прямоугольник.

Таким образом , мы можем поставить все количество упорядоченного по количеству вхождений, то \ (O \ влево (\ SQRT NlogN \ справа) \) время и количество штук провели Рассчитайте размер самого большого прямоугольника, а затем с помощью \ (O ( п) \) есть число раз , чтобы заполнить конечную временную сложность является \ (о (NlogN + \ SQRT NlogN + п) \)

Код

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <map>
using namespace std;

#define RG register int
#define LL long long

template<typename elemType>
inline void Read(elemType &T){
    elemType X=0,w=0; char ch=0;
    while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    T=(w?-X:X);
}

struct Node{int Num,Cnt;};
map<int,int> Hash;
vector<Node> Com;
vector<int> Data;
vector<int> Mat[1000];

int Sum[400010];
int N,Row=0,Col=0,Total=0;

bool cmp(Node A,Node B){return A.Cnt>B.Cnt;}

inline int Judge(int row){
    int Pos=upper_bound(Data.begin(),Data.end(),row)-Data.begin()-1;
    int Res=(Sum[Pos]+((int)Data.size()-Pos-1)*row)/row*row;
    if(Res/row<row) return 0;
    return Res;
}

int CountY=0;

inline void Move(int &px,int &py){
    if(px==Row-1) ++CountY;
    if(px+1<Row && py+1<Col){++px;++py;return;}
    if(px+1>=Row && py+1<Col){px=0;py=CountY;return;}
    if(px+1<Row && py+1>=Col){py=0;++px;return;}
    if(px+1>=Row && py+1>=Col){px=0;py=CountY;return;}
    return;
}

inline void Maintain(){
    int px=0,py=0;
    for(RG i=1;i<=Col;++i)
        for(RG j=0;j<Row;++j)
            Mat[j].push_back(0);
    for(int i=0;i<(int)Com.size();++i){
        int Num=Com[i].Num,Cnt=min(Com[i].Cnt,Row);
        for(RG i=1;i<=Cnt;++i){
            Mat[px][py]=Num;
            Move(px,py);
        }
    }    
    for(RG i=0;i<Row;++i){
        for(RG j=0;j<Col;++j){
            printf("%d",Mat[i][j]);
            if(j<Col-1) printf(" ");
        }
        printf("\n");
    }
    return;
}

int main(){
    Read(N);
    for(RG i=1;i<=N;++i){
        int x;Read(x);
        ++Hash[x];
    }
    Data.push_back(-2147483647);
    for(auto it:Hash){
        Data.push_back(it.second);
        Com.push_back((Node){it.first,it.second});
    }
    sort(Com.begin(),Com.end(),cmp);
    sort(Data.begin(),Data.end());
    for(RG i=1;i<(int)Data.size();++i)
        Sum[i]=Sum[i-1]+Data[i];
    for(RG i=1;i*i<=N;++i){
        int temp=Judge(i);
        if(temp>Total){Total=temp;Row=i;}
    }
    Col=Total/Row;
    printf("%d\n%d %d\n",Total,Row,Col);
    Maintain();
    return 0;
}

рекомендация

отwww.cnblogs.com/AEMShana/p/12389152.html