个格子,编号从 到 ,染成 种颜色,每种颜色恰好 个。
构造 个区间,第 个区间 满足
- 第 个和第 个格子的颜色都是 。
- 每个格子被包含不超过 次。
,。
先求出 表示颜色 第 次出现的位置。
不难发现,只要把 个颜色分为 组,每组大小 ,不同组的区间互不相交即可。并且每个颜色选择区间 肯定是最优的。
考虑较为简单的情况的构造, 未免太简单了,考虑 的情况。这时要分 组,每组大小 ,稍加思考可以发现,只要按照 排序,前 个颜色选择区间 ,其它颜色选择区间 即可。
考虑推广这个构造方法,容易发现,只要重复 次,第 次按照 排序,排序后前 个颜色选择区间 即可。
代码如下:
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int S=105;
int n,k;
int pos[S][S],tot[S];
int ansl[S],ansr[S];
int id[S];
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n*k;i++)
{
int x;
scanf("%d",&x);
pos[x][++tot[x]]=i;
}
int val=n/(k-1)+!!(n%(k-1));
for(int i=1;i<=k-1;i++)
{
int cnt=0;
for(int j=1;j<=n;j++) if(ansl[j]==ansr[j]) id[++cnt]=j;
sort(id+1,id+cnt+1,[&](int x,int y){return pos[x][i+1]<pos[y][i+1];});
for(int j=1;j<=cnt&&j<=val;j++) ansl[id[j]]=pos[id[j]][i],ansr[id[j]]=pos[id[j]][i+1];
}
for(int i=1;i<=n;i++) printf("%d %d\n",ansl[i],ansr[i]);
return 0;
}