HDU - 1808 Halloween treats(鸽巢原理)

2023-10-31

Halloween treats

Every year there is the same problem at Halloween: Each neighbour is only willing to give a certain total number of sweets on that day, no matter how many children call on him, so it may happen that a child will get nothing if it is too late. To avoid conflicts, the children have decided they will put all sweets together and then divide them evenly among themselves. From last year’s experience of Halloween they know how many sweets they get from each neighbour. Since they care more about justice than about the number of sweets they get, they want to select a subset of the neighbours to visit, so that in sharing every child receives the same number of sweets. They will not be satisfied if they have any sweets left which cannot be divided.

Your job is to help the children and present a solution.

Input
The input contains several test cases.
The first line of each test case contains two integers c and n (1 ≤ c ≤ n ≤ 100000), the number of children and the number of neighbours, respectively. The next line contains n space separated integers a1 , … , an (1 ≤ ai ≤ 100000 ), where ai represents the number of sweets the children get if they visit neighbour i.

The last test case is followed by two zeros.

Output
For each test case output one line with the indices of the neighbours the children should select (here, index i corresponds to neighbour i who gives a total number of ai sweets). If there is no solution where each child gets at least one sweet, print “no sweets” instead. Note that if there are several solutions where each child gets at least one sweet, you may print any of them.
Sample Input
4 5
1 2 3 7 5
3 6
7 11 2 5 13 17
0 0
Sample Output
3 5
2 3 4

题意: 输入 c ,n ,当 c 与 n 同时为0时程序结束,给你n个正整数(1<= c <= n <= 1e5 )你可以从这 n 个数里面随便取任意数,当这 n 个数和可以整除 c 时输出这n个数的下标(从1开始计数),答案有多种时输出任意一种。不存在时输出“no sweets”。

思路: 给你一个长度为 n 的序列,其中至少有一段长度为 k 的连续序列和可以整除 c(c <= n)(证明为鸽巢原理,详细在下面),所以不存在"no sweets" 的情况,所以我们只需要找到这段序列的头和尾就行,然后直接输出这段连续的下标。如果我们用前缀和存数据然后用两个循环找出这段序列,会造成程序超时。如果我们对每一个前缀和的数据对 c 进行取余,然后用一个循环遍历每一个前缀取余判断其是否是第二次出现,若是第二次出现那么第一次出现的下标加一即为头,第二次出现的下标即为尾,我们直接输出就可以了。

证明: 给你以一个长度为 n 的序列,我们可以得到一个长度为 n 的前缀和序列,我们令每一个前缀和为Si(Si = a1 + a2 + … +ai)。对每一个Si 进行取余 c 我们会得到一个长度为 n 的取余序列我们令它为Mi(Mi = Si % c) 那么Mi 会有 c-1 种可能(除了0以外),也就是说,一个长度为 n 的序列它的结果只有 c - 1种可能,并且很明显 n > c-1,所以一定存在Ml 等于 Mr(抽象出来就是一共有c - 1个鸽巢,但我们有 n 只鸽子要进入巢中,所以肯定存在一个鸽巢的鸽子数量超过了 2 ,也就意味着在M这个序列中一定存在有两个数是相同的),既然 Ml 等于 Mr 那么也就意味着在a数组下标 l + 1 到 r的和是可以整除 c 的即前缀和 (Sr - Sl)%c 等于 0(例子:16 % 3 等于 1,4%3等于1,那么(16 - 4)% 3 等于0),k = r - l。

#include <string.h>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdexcept>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define ll long long
#define int long long
const int maxn = 1e5 + 10;
const int inf = 0x3f3f3f3f;
const int Base = 131;
const ll INF = 1ll << 62;
const double PI = acos(-1);
const double eps = 1e-7;
const int mod = 2147493647;
#define PI acos(-1)
#define mem(a, b) memset(a, b, sizeof(a))
#define speed { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0);}

// inline int gcd(int a, int b) {
// 	while (b ^= a ^= b ^= a %= b);
// 	return a;
// }

inline ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }

long long fastPower(long long base, long long power)
{
	long long result = 1;
	while (power > 0)
	{
		if (power & 1)
			result = result * base % mod;
		power >>= 1;
		base = (base * base) % mod;
	}
	return result;
}

inline ll rd()
{
	ll s = 0, w = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9')
	{
		if (ch == '-')
			w = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9')
		s = s * 10 + ch - '0', ch = getchar();
	return s * w;
}

int a[maxn], prefix[maxn], index[maxn];

signed main(){
	int c, n;
	while(~scanf("%lld %lld", &c, &n), c || n){
		int p = 0;
		for(int i = 1; i <= n; i++){
			a[i] = rd();
			prefix[i] = (prefix[i-1] + a[i]) % c; // 对前缀和进行取余
			if(prefix[i] == 0) p = i; // 如果已经出现取余为0的情况直接输出就好了
			index[i] = -1;
		}
		if(p){
			for(int i = 1; i <= p; i++)
				printf("%lld%c", i, " \n"[i == p]);
		}else{
			for(int i = 1; i <= n; i++){
				if(index[prefix[i]] != -1){ //判断这个余数是否是第二次出现
					for(int j = index[prefix[i]] + 1; j <= i; j++)
						printf("%lld%c", j," \n"[j == i]);
					break;
				}else{
					index[prefix[i]] = i; // 如果是第一次出现直接标上第一次出现的下标
				}
			}
		}
	}
	//system("pause");
	return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HDU - 1808 Halloween treats(鸽巢原理) 的相关文章

随机推荐

  • pinia 入门教程

    文章目录 pinia介绍 一 pinia安装 二 创建 pinia 实例 三 创建store文件 1 options store 2 setup store 四 state 1 定义state 2 使用state 3 修改state值 4
  • Vue2:官方路由 Vue-Router 3.x

    前端路由 前端路由 根据不同的url地址 页面上展示不同的内容 根据url地址的不同分发到不同的组件 SPA 介绍 spa 是 single page application 简写 意思是单页面应用程序 Vue 适合开发 spa 类型的项目
  • Tom DeMarco:软件工程这个概念已过时?

    原文作者 Tom Demarco 写于2009年7月 作者简介 Tom DeMarco是大西洋系统协会 www atlsysguild com 的负责人 他的职业生涯开始于贝尔实验室 是结构化分析和设计的创始人之一 研究领域主要集中在对软件
  • 浏览器控制台报错:Cross origin requests are only supported for protocol schemes

    浏览器控制台报错 Cross origin requests are only supported for protocol schemes 一 问题 二 原因分析 三 解决方法 一 问题 今天写了一个H5 的小demo 然后在浏览器中运行
  • 管理系列:项目管理之项目汇报总结

    项目汇报是项目实施过程中到达某一节点时 项目经理将项目的开发成果给用户展示介绍 防止项目开发方向与客户期望方向不符 以及推动项目上线运行的关键环节 所以项目汇报的效果对项目的进展方向 推进速度有很重要的影响 所以 在项目汇报之前一定要准备充
  • 编译原理 课程设计 LR(1)分析法

    作业目的 构造LR 1 分析程序 利用它进行语法分析 判断给出的符号串是否为该文法识别的句子 了解LR K 分析方法是严格的从左向右扫描 和自底向上的语法分析方法 作业题目 1 对下列文法 用LR 1 分析法对任意输入的符号串进行分析 0
  • SpringCloud Ribbon

    负载均衡分为服务端负载均衡和客户端负载均衡 SpringCloud Ribbon是基于客户端的负载均衡工具 客户端负载均衡和服务端负载均衡的区别在于客户端要维护一份服务列表 Ribbon从Eureka server中获取服务列表 根据负载均
  • 到底什么是CLI?

    前端写了这么久 经常用Vue cli webpack cli react cli这些工具 但不怕大家笑话 这些名词我一直不知道啥意思 我也查了资料 网上都说它们叫脚手架或者命令行工具 但对我来说我只是又多知道了几个名称 直到最近接触linu
  • Error (3, 32) java 程序包org springframework boot不存在

    Error 3 32 java 程序包org springframework boot不存在 1 出现的问题 java 程序包org springframework boot不存在 idea安装2020 1 1后踩的坑 2 解决办法 两种
  • 单片机与PLD(可编程逻辑器件)的联系与区别

    站外链接 http m dzsc com data 2017 6 19 112438 html
  • 前端excel写入信息并下载

    需要npm install xlsx 安装xlsx依赖 const data management zh cn 管理 en us function dataToFormat data let newdata for let i in dat
  • JS对象(一)

    http evanwukong blog 163 com blog static 134836495201232554038203 JavaScript 是面向对象的 但是不少人对这一点理解得并不全面 在 JavaScript 中 对象分为
  • linux下GPRS ppp拨号默认路由问题(存在eth0)

    问题描述 linux版本是Linux 2 6 33 rc4 第一种情况 eth0 192 168 1 2 eth0 gw 192 168 1 1 ppp0 10 0 0 1 eth0的IP地址和gw在同一个网段下 此时的默认路由是 Dest
  • 幂等性概念与解决方案

    幂等性概念 幂等性原本是数学上的概念用在编程领域 则意为对同一个系统 使用同样的条件 一次请求和重复的多次请求对系统资源的影响是一致的 幂等性原本是数学上的概念 即使公式 f x f f x 能够成立的数学性质 编程领域 则意为对同一个系统
  • 条件变量详细解说

    1 条件变量概述 条件变量是用来等待线程而不是上锁的 条件变量通常和互斥锁一起使用 条件变量之所以要和互斥锁一起使用 主要是因为互斥锁的一个明显的特点就是它只有两种状态 锁定和非锁定 而条件变量可以通过允许线程阻塞和等待另一个线程发送信号来
  • lnmp1.4上thinkphp5.0出现404的解决办法

    气死了 tp5在Nginx上不适用pathinfo格式的url 在项目的Nginx配置文件里找到include enable php conf 改为 include enable php pathinfo cof 然后就可以了
  • 电子小模块

    1 步进电机 ULN2003驱动板4相5线 一一一一一一一一一一一一一一一一一一一一一一一一一一一一一 2 红外传感器模块 https pan baidu com s 1QR Z4Qq02ViaVl8wyyoWeg 提取码 knbw 一一一
  • 【点云】SemanticKITTI: A Dataset for Semantic Scene Understanding of LiDAR Sequences

    目录 摘要 介绍 SemanticKITTI Dataset 标注过程 摘要 自动驾驶需要对附近的目标和表面有细颗粒度 fine grained 的理解 光检测和范围 LiDAR 提供了关于环境准确的几何信息 目前 缺少一个基于移动LiDA
  • 程序猿做副业,偷偷告诉你个方法!请勿外传。

    身为程序猿 年轻的时候总觉得 只要我好好写代码 安心于技术 努力提高技能 即便不走管理者路线 在岗位上认真负责做出成绩 就能升职加薪 走上人生巅峰 到了三十多岁才发现 曾经太天真了 技术见长 头发变少 工资已经摸到天花板 但固定的开销必不可
  • HDU - 1808 Halloween treats(鸽巢原理)

    Halloween treats Every year there is the same problem at Halloween Each neighbour is only willing to give a certain tota