当前位置: 首页 > article >正文

Colors and Intervals

Colors and Intervals

n × k n \times k n×k 个格子,编号从 1 1 1 n × k n \times k n×k,染成 n n n 种颜色,每种颜色恰好 k k k 个。
构造 n n n 个区间,第 i i i 个区间 [ a i , b i ] [a_i, b_i] [ai,bi] 满足

  • 1 ≤ a i < b i ≤ n × k 1 \le a_i < b_i \le n \times k 1ai<bin×k
  • a i a_i ai 个和第 b i b_i bi 个格子的颜色都是 i i i
  • 每个格子被包含不超过 ⌈ n k − 1 ⌉ \lceil \frac{n}{k-1} \rceil k1n 次。

样例 #1

样例输入 #1

4 3
2 4 3 1 1 4 2 3 2 1 3 4

样例输出 #1

4 5
1 7
8 11
6 12

样例 #2

样例输入 #2

1 2
1 1

样例输出 #2

1 2

样例 #3

样例输入 #3

3 3
3 1 2 3 2 1 2 1 3

样例输出 #3

6 8
3 7
1 4

样例 #4

样例输入 #4

2 3
2 1 1 1 2 2

样例输出 #4

2 3
5 6

题目要求每个格子被包含不超过 ⌈ n k − 1 ⌉ \lceil \dfrac{n}{k-1} \rceil k1n ,那我们可以考虑每次求出 k − 1 k-1 k1不连续的区间,总共求出 n n n 个后,即可确保每段被包含的次数满足条件。

先来证明每次都能求出 k − 1 k-1 k1 个区间:

可以用数学归纳法来证明。证明的命题为:对于 k − 1 k-1 k1 种颜色(由于此时要取 k − 1 k-1 k1 个区间,只与 k − 1 k-1 k1 个颜色有关,其他颜色在其他轮的取区间中再考虑),每种 k k k 个,可以去到 k − 1 k-1 k1 个区间。

  • k = 2 k=2 k=2 时,一种颜色,且有两个,显然成立。
  • 假设 k = k 1 − 1 k=k_1-1 k=k11 时成立,对于 k 1 − 2 k_1-2 k12 种颜色,每种 k 1 − 1 k_1-1 k11 个,可以取到 k 1 − 2 k_1-2 k12 个区间。
  • k = k 1 k=k_1 k=k1 时,令第一个取到的区间为 [ l 1 , r 1 ] [l_1,r_1] [l1,r1] ,可以证明 [ 1 , r 1 − 1 ] [1,r_1-1] [1,r11] 中没有一种颜色出现两次(若有,则 r 1 r_1 r1 可以更小),此时一种颜色被取过后,不需要考虑这种颜色,所以此时颜色还剩 k 1 − 2 k_1-2 k12 种,每种 k 1 − 1 k_1-1 k11 k 1 k_1 k1 个,显然,每种颜色越多,越容易取到区间,所以可令每种还有 k 1 − 1 k_1-1 k11 个,要取 k 1 − 2 k_1-2 k12 个区间,所以命题成立。

考虑每次如何取区间,取到 [ l 1 , r 1 ] [l_1,r_1] [l1,r1] 后,清空记录的前驱信息,从 r 1 + 1 r_1+1 r1+1 开始遍历,然后取区间。

注意题目要求每个区间要按颜色输出。

Code:

#include<bits/stdc++.h>
using namespace std;
const int N=110;
int n,k,cnt,pre[N],a[N*N];
bitset<N> vis;
pair<int,int> ans[N];
//ans记录答案,vis记录颜色是否取过
//cnt记录还能取几个区间
//pre记录每个颜色最后出现的位置
int main(){
    scanf("%d%d",&n,&k);cnt=n;
    for(int i=1;i<=n*k;i++) scanf("%d",&a[i]);
    while(cnt){
        for(int i=1;i<=n*k;i++){
            if(vis[a[i]]) continue;
            if(pre[a[i]]){
                ans[a[i]]={pre[a[i]],i};
                cnt--;
                vis[a[i]]=1;
                memset(pre,0,sizeof(pre));
            }
            else pre[a[i]]=i;
        }
        memset(pre,0,sizeof(pre));
    }
    for(int i=1;i<=n;i++) printf("%d %d\n",ans[i].first,ans[i].second);
    return 0;
}


http://www.kler.cn/a/409070.html

相关文章:

  • 【GPT】睡觉时,大脑在做什么
  • Linux:自定义Shell
  • Mac配置maven环境及在IDEA中配置Maven
  • 深度学习之目标检测的常用标注工具
  • CSP/信奥赛C++语法基础刷题训练(23):洛谷P1217:[USACO1.5] 回文质数 Prime Palindromes
  • python代码制作数据集的测试和数据质量检测思路
  • vue项目中中怎么获取环境变量
  • Spring Boot OA:企业办公自动化的高效路径
  • 设计模式——组合实体模式
  • 7-366 解救小鱼干
  • 大数据背景下的数据质量挑战与解决方案
  • 【数据分享】2024年我国省市县三级的住宿服务设施数量(8类住宿设施/Excel/Shp格式)
  • PostgreSQL的内存结构
  • Unity 使用 ExcelDataReader 读取Excel表
  • Ubuntu,openEuler,MySql安装
  • 力扣797. 所有可能的路径
  • 什么是Webpack,有什么特点
  • 基于FPGA(现场可编程门阵列)的SD NAND图片显示系统是一个复杂的项目,它涉及硬件设计、FPGA编程、SD卡接口、NAND闪存控制以及图像显示等多个方面
  • 【LeetCode】每日一题 2024_11_21 矩阵中的蛇(模拟)
  • 【机器学习】超简明Python基础教程
  • 数据抓取与存储:将网络爬虫数据保存到数据库的详细指南
  • 缓存大key如何解决
  • 基于Java Springboot餐饮美食分享平台
  • 【隐私计算大模型】联邦深度学习之拆分学习Split learning原理及安全风险、应对措施以及在大模型联合训练中的应用案例
  • BLIP-2模型的详解与思考
  • Docker+PostgreSQL数据库