1. 程式人生 > 實用技巧 >F. Beautiful Rectangle 構造

F. Beautiful Rectangle 構造

F. Beautiful Rectangle

題解:

本來這個題目不準備寫題解了的,因為這個確實不是很難,但是我wa了很多次之後,發現還是有寫的必要。

這個題目首先求出p和q,這個不是很難求,就是統計每一個數字的數量,然後排序一下,求出每一個寬 x 可以放進去的最多的數量。

求出 p q之後就是構造一個解即可。

但是這個構造要注意 一定是要 row<=col 也就是說 行的數量要小於等於列的數量,而不是列的數量小於等於行的數量。

這個是為什麼呢?

就看看3 5 感性理解一下吧

1 4 7 10 13

14 2 5 8 11

12 15 3 6 9

5 3

1 6 11

12 2 7

8 13 3

4 9 14

15 5 10

對於第二個 5和6 10和11是排在一塊的,而對於第一個則沒有這樣的情況。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 4e5+10;
typedef long long ll;
int a[maxn],v[maxn],num[maxn],val[maxn],sum[maxn],c[maxn];
map<int,int>mp[maxn];
bool cmp(int a,int b){
	return num[a]>num[b];
}
int main() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &v[i]);
        a[i] = v[i];
        c[i]=i;
    }
    sort(v + 1, v + 1 + n);
    int len = unique(v + 1, v + 1 + n) - v - 1;
    for (int i = 1; i <= n; i++) {
        int pos = lower_bound(v + 1, v + 1 + len, a[i]) - v;
        num[pos]++, val[pos] = num[pos];
    }
    sort(val + 1, val + 1 + len);
    for (int i = 1; i <= len; i++) {
        int x = lower_bound(val + 1, val + 1 + len, i) - val;
//        printf("i=%d x=%d val=%d\n",i,x,val[i]);
        sum[i] = sum[i - 1] + len - x + 1;
    }
    int p = 1, q = 1, maxs = 0;
    for (int i = 1; i <= sqrt(n); i++) {
        int res = sum[i] / i * i;
        if(sum[i]/i<i) continue;
//        printf("i=%d sum=%d res=%d\n",i,sum[i],res);
        if (res > maxs) {
            maxs = res;
            p = i;
            q = sum[i] / i;
        }
    }
//    printf("p=%d q=%d\n",p,q);
    int sx = 0, sy = 0,now = 0;
    sort(c+1,c+1+len,cmp);
    for (int i = 1; i <= len; i++) {
    	int id = c[i];
        for (int j = 1; j <= min(p, num[id]); j++) {
            mp[sx][sy] = v[id];
            sy=(sy+1)%q, sx=(sx+1)%p;
            if(!sx){
            	++now;
            	sx = 0,sy = now;
			}
        }
    }
    printf("%lld\n",1ll*p*q);
    printf("%d %d\n",p,q);
    for(int i=0;i<p;i++){
        for(int j=0;j<q;j++){
            printf("%d ",mp[i][j]);
        }
        printf("\n");
    }
}