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
exactlyn2).
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
二分的好题目,首先直接求不知道怎么求,那就想到枚举每一个,这样就产生了二分的思想,二分出结果后,在对结果输出,这样就不会超时了
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<cmath>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define inf 0x0f0f0f0fusing namespace std;
const int maxn=100000+10;int type[maxn],n,m;
bool find_if(int x)
{
int cut=0;
for (int i=1;i<=m;i++)
{
if (cut==n) break;
cut+=type[i]/x;
}
if (cut>=n){
return true;
}
else return false;
}int find(int x,int y)
{
while (x<y)
{
int mid=x+(y-x)/2;
if (find_if(mid)) x=mid+1;
else y=mid;
}
return x-1;
}int main()
{
int x;
while(scanf("%d%d",&n,&m)!=EOF)
{
for (int i=1;i<=m;i++)
{
scanf("%d",&type[i]);
}
int ans=find(1,n+1);
printf("%d\n",ans);
int i=1;
while(n)
{
while(type[i]>=ans && n)
{
printf("%d\n",i);
n--;
type[i]-=ans;
}
i++;
}
}
return 0;
}
作者 chensunrise
poj 3388 Japanese Puzzle,布布扣,bubuko.com