[Configuration] Codeforces 1276C / 1278E Beautiful Rectangle

Subject to the effect

We call a matrix is ​​beautiful, if and only if two of the same number that does not exist in the same column or matrix in the same row.

Given \ (n \) number, asking you to select as many numbers to enable them to make up a beautiful rectangle.

Note that, the present title number of the selected output required number and composition of the specific programs and the rectangle size.

\(n\leq 4 \times 10^5\)

answer

Think for several days, finally figured it out, I really was too much food ...

First of all, it is conceivable for a \ (x \) rectangular lines (so the number of columns greater than or equal the number of rows), if there has been a number of more than \ (x \) times, and this number is impossible to fill all of the rectangle and you can only fill \ (X \) a, i.e. obliquely to fill in, press the sequence diagram.

Then we use a map maintenance times each number appears, press the number of occurrences of descending to fill the number, the same number of filling together. Why Yaoan descending number appears to fill it? If you just fill it, it will be hack out this set of data.

7
8 5 10 4 10 8 3

My answer is

6
2 3
3 5 8
10 4 8

The correct answer is

6
2 3
8 10 3
4 8 10

Although the discovery is placed at an angle to fill, but even listed in the same two 8. It can be shown by the number of occurrences of descending to fill the number, it will not be the case.

Then we must first determine how many lines of this rectangle, from the \ (1 \ sim \ sqrt n \) held a few pieces to go, assuming that the number of rows to the current enumeration of \ (Row \) , then for each number, the most we take \ (Row \) views, can calculate the number of the number of total we can take the prefix and + bipartite \ (Cnt \) , then we can calculate the number of rows \ (Col = \ left \ lfloor \ frac {Cnt} row} {\ right \ rfloor \ Times row \) , but \ (CoI \) is not less than \ (row \) , otherwise not meet the number of columns equal to the number of rows is greater than our previously defined. Can prove the existence of a certain filling method, which can fill the \ (Row \ times Col \) rectangle.

So we can put all the number ordered by the number of occurrences, then \ (O \ left (\ sqrt nlogn \ right) \) time and the number of pieces held calculate the size of the largest rectangle, and then using the \ (O ( n-) \) is the number of times to fill the final time complexity is \ (O (nlogn + \ sqrt nlogn + n) \)

Code

#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;
}

Guess you like

Origin www.cnblogs.com/AEMShana/p/12389152.html