POJ 3388 Japanese Puzzle(二分法)

大体题意:

给你一个n*n 的图,你总共有k 种花砖,告诉你每一种花砖的个数,你可以任意安排花砖!问最多有几行 他们的图案是一样的?

思路:

二分法:

直接二分答案 行数,  在看每一种花砖 在每一行中的个数,这样累加 直到累加到 n 就说明当前的行数 是可行的,用个变量更新一下!  最后二分完毕后  就是最大行数!

然后打印解!

个人觉得 这个打印解真的好烂!    输出为n 行,任意输出图案的编号,该编号一定存在,一个编号可以输出多次!

不过这个题目的思想还是很好的!


其实最气的 还是 用G++死活都是超时, C++就可以过了!

#include <cstdio>
#include <cstring>
#include <algorithm>
#define Min(a,b) (a) > (b) ? (b) : (a)
#define Max(a,b) (a) > (b) ? (a) : (b)
using namespace std;
const int maxn = 50000 + 7 ;
int n, k;
struct Node{
    int id,v;
    bool operator < (const Node& rhs) const {
        return v > rhs.v;
    }
    void read(int i){
        scanf("%d",&v);
        id = i;
    }
}p[maxn];
bool judge(int mid){
    if (!mid) return 0;
    int sum = 0;
//    printf("%d\n",mid);
    for (int i = 0; i < k; ++i){
        if (sum >= n) return 1;
        if (p[i].v / mid < 1) return 0;
        sum += p[i].v / mid;
//        printf("sum = %d\n",sum);
    }
//    printf("%d\n",mid);
    return sum >= n;
}
void print(int ans){
    int sum = 0;
    for (int i = 0; i < k; ++i){
        int t = p[i].v / ans;
//        printf("t = %d\n",t);
        if (sum + t <= n){
            for (int j = 0; j < t; ++j)printf("%d\n",p[i].id);
        }
        else {
            for (int j = 0; j < n - sum; ++j)printf("%d\n",p[i].id);
            return ;
        }
        sum += t;
    }
}
int main(){
    scanf("%d %d",&n, &k);
    for (int i = 0; i < k; ++i){
        p[i].read(i+1);
    }
    sort(p,p+k);
    int l = 1,r = 50001;
    int ans= -1;
    while(l <= r){
        int mid = l + r >> 1;
        if (judge(mid))ans = Max(mid,ans),l = mid + 1;
        else r = mid-1;
//        printf("rr  rrrr   %d\n",r);
    }
    printf("%d\n",ans);
    print(ans);
    return 0;
}

Japanese Puzzle
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 2214 Accepted: 628 Special Judge

Description

A brand-new Japanese puzzle is coming from the East to strike the world-popular Sudoku game and become an international hit. The rules of this puzzle are kept in secret yet, but the goal is already advertised: given a square grid n × n, where each square contains a block with one of k types of pictures, the player has to rearrange it to get the maximal possible number of equal first rows (two rows are considered equal if both of them are filled with the same pictures in the same order). An unnamed insider of the game production company told the press that the game is about moving blocks of pictures according to some rules, while the overall set of pictures isn’t changed (no pictures removed, no new pictures added). She also mentioned that the puzzle is so exciting because there are thousands of ways to swap two arbitrary pictures on a grid leaving the rest of the grid intact.

Andy works at the puzzles review magazine, and of course he got interest in this Japanese news. He realized that the information known so far is enough to find the number of equal first rows in a puzzle winning position. Now Andy wants to write a computer program for calculating this number for any given starting configuration.

For example, if you are given a puzzle which looks this way:

+

one of the optimal rearrangements could look like

+

Input

The first line of the input file contains two integers n (1 ≤ n ≤  40 000 ) and k (1 ≤ k ≤  50 000 ). Each of the next k lines contains the number of blocks with the corresponding type of picture li (li > 0, sum of all li is exactly n2).

Output

Output the maximal possible number of equal first rows at the first line of the output file. The following n lines must contain contents of the row which gives the maximum. Each line shows a single number of picture, in order they must appear. If there are many optimal solutions, any is acceptable.

Sample Input

3 4
3
3
2
1

Sample Output

2
1
2
3

Source

Northeastern Europe 2006, Northern Subregion

[Submit]   [Go Back]   [Status]   [Discuss]



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值