• 好吃的巧克力题解


    题目描述

    超市正在特价售卖巧克力,正好被贪吃的 Lucky_dog 看见了。
    巧克力从左到右排成一排,一共有 N 个,M 种。
    超市有一个很奇怪的规定,就是你在购买巧克力时必须提供两个数字 a 和 b,代表你要购买第 a 个至第 b 个巧克力(包含 a 和 b)之间的所有巧克力。
    假设所有巧克力的单价均为 1 元。Lucky_dog 想吃所有种类的巧克力,但又想省钱。作为 Lucky_dog 的朋友,他请你来帮他决定如何选择购买巧克力时的 a 和 b。

    输入格式:
    第一行包含两个正整数 N 和 M,分别代表巧克力的总数及种类数。
    第二行包含 N 个整数,这些整数均在1 至 M 之间,代表对应的巧克力所属的种类。

    输出格式:
    输出仅一行,包含两个整数 a 和 b,由一个空格隔开,表示花费最少且包含所有种类巧克力的购买区间。
    数据保证有解,如果存在多个符合条件的购买区间,输出 a 最小的那个。

    解题思路

    1.选定头部后,每出现一种新的种类,计数器加一
    2.当头部种类出现两次,头部右移一位
    贪心算法的思想:如果头部种类出现两次,那么肯定不是最优解,至少头部右端更优
    3.满足条件,更新数据 a,b

    完整代码

    #include<stdio.h>
    int main()
    {
    	int n, m, i, a, b, cnt = 0, head = 0, d = 1000020;
    	static int p[1000020], num[2020] = { 0 };
    	scanf("%d%d", &n, &m);
    	for (i = 0; i < n; i++) {
    		scanf("%d", &p[i]);
    		if (num[p[i]] == 0) {
    			cnt++;
    		}/*出现新的种类,计数器加一*/
    		num[p[i]]++;
    		while (num[p[head]] > 1) {
    			num[p[head]]--;
    			head++;
    		}/*头部种类出现两次,头部右移一位*/
    		if (cnt == m) {
    			if (i - head + 1 < d) {
    				d = i - head + 1;
    				a = head;
    				b = a + d - 1;
    			}
    		}/*满足条件,更新数据 a,b*/
    	}
    	printf("%d %d", a + 1, b + 1);
    	return 0;
    }
  • 相关阅读:
    SIFT 特征提取算法总结
    Bilateral Filtering(双边滤波) for SSAO(转)
    Meanshift filter实现简单图片的卡通化效果
    HBM内存介绍
    DRAM 内存介绍(三)
    Arduino教程:MPU6050的数据获取、分析与处理
    pitch yaw roll是什么
    通过经纬度坐标计算距离的方法(经纬度距离计算)ZZ
    关于已知两点经纬度求球面最短距离的公式推导
    [Math]理解卡尔曼滤波器 (Understanding Kalman Filter)
  • 原文地址:https://www.cnblogs.com/dump16/p/12539230.html
Copyright © 2020-2023  润新知