Hackerearth.com编程问题解题思路系列:Roy's Chocolates
2015-12-30 21:50
316 查看
问题描述:
设从1至n编号的n人围成一圈,给出序号M[i]的m人是被标记的,从序号为b的人开始,每过s人答一声“到”。要求找出这样的b和s,使得被标记的m人全部都答过一声“到”,而没有被标记过的人不答“到”。n在10^9量级,m在10^6量级。
问题分析:
最原始的方法是枚举s和b,时间复杂度为O(n^2*m),由于n,m的量级比较大,所以不能直接硬举,要先寻找一些规律,再配合搜索进行求解。
首先将M[i]在坐标轴上画下来:将1到n向右在坐标轴上扩展,令M1,M2...Mm分别为第1,2...,m个答到的人,按每隔s的顺序在坐标轴上标出,如下图:
注:图中相邻两个M之间距离为s
经观察得出:
将上面所有式相加,并在两边各加上M1,得到:
式中m与各个Mi之和是已知的,M1即是出发点b,是枚举的对象,还差一个s没有确定,如果枚举s,可以先确定出s的范围。
这时将公式改写成如下形式:
而t是可以确定的:
[x]为取整函数(不超过x的最大整数)
于是可得:
整理得:
这时s的范围可以定得比较小,枚举s基本上花费常数时间,算法整体的时间复杂度是O(n)
Python代码:
n,m=[int(i) for i in raw_input().split()]
M=[int(i) for i in raw_input().split()]
def calc():
global n,m
global M
if m==1:
print "%d %d"%(M[0],n)
return
sumM=sum(M)
for i in range(m):
left=int((sumM-m*M[i]-n)*2/(m-2)/(m-1))
if left<=0:
left=1
right=int((sumM-m*M[i])*2/(m-2)/(m-1))+1
#print left,right
for l in range(left,right+1):
if int((m*M[i]+m*(m-1)*l/2))%n==sumM%n and (M[i]+l) in M and (M[i]+2*l) in M:
print "%d %d"%(M[i],l)
return
print "impossible"
calc()
原题:https://www.hackerearth.com/problem/approximate/roys-chocolates/
Roy has brought one chocolate for each of his m friends to class today. After knowing that, all of his n classmates demanded chocolates from him. But Roy wanted to give
chocolates only to his friends.
So, he told them to stand in a circle around him, where the 1st student stands next to the nth one. Then Roy will follow a strategy to distribute
the chocolates. He will start by giving chocolate to some person b, and will continue to give chocolate to every sth person. After someone receives chocolate,
s/he does not leave the circle.
Roy noticed the positions of his friends, and now he wants to choose b and s in such a way that, only and all of his friends get those chocolates.
The first line of input contains 2 space separated integers, n and m, number of Roy's classmates and number of Roy's friends.
The next line contains m space separated integers, the positions of Roy's friends.
1 ≤ n ≤ 10 9
1 ≤ m ≤ 10 6
m ≤ n
positions of Roy's friends will be given in increasing order.
设从1至n编号的n人围成一圈,给出序号M[i]的m人是被标记的,从序号为b的人开始,每过s人答一声“到”。要求找出这样的b和s,使得被标记的m人全部都答过一声“到”,而没有被标记过的人不答“到”。n在10^9量级,m在10^6量级。
问题分析:
最原始的方法是枚举s和b,时间复杂度为O(n^2*m),由于n,m的量级比较大,所以不能直接硬举,要先寻找一些规律,再配合搜索进行求解。
首先将M[i]在坐标轴上画下来:将1到n向右在坐标轴上扩展,令M1,M2...Mm分别为第1,2...,m个答到的人,按每隔s的顺序在坐标轴上标出,如下图:
注:图中相邻两个M之间距离为s
经观察得出:
将上面所有式相加,并在两边各加上M1,得到:
式中m与各个Mi之和是已知的,M1即是出发点b,是枚举的对象,还差一个s没有确定,如果枚举s,可以先确定出s的范围。
这时将公式改写成如下形式:
而t是可以确定的:
[x]为取整函数(不超过x的最大整数)
于是可得:
整理得:
这时s的范围可以定得比较小,枚举s基本上花费常数时间,算法整体的时间复杂度是O(n)
Python代码:
n,m=[int(i) for i in raw_input().split()]
M=[int(i) for i in raw_input().split()]
def calc():
global n,m
global M
if m==1:
print "%d %d"%(M[0],n)
return
sumM=sum(M)
for i in range(m):
left=int((sumM-m*M[i]-n)*2/(m-2)/(m-1))
if left<=0:
left=1
right=int((sumM-m*M[i])*2/(m-2)/(m-1))+1
#print left,right
for l in range(left,right+1):
if int((m*M[i]+m*(m-1)*l/2))%n==sumM%n and (M[i]+l) in M and (M[i]+2*l) in M:
print "%d %d"%(M[i],l)
return
print "impossible"
calc()
原题:https://www.hackerearth.com/problem/approximate/roys-chocolates/
Roy has brought one chocolate for each of his m friends to class today. After knowing that, all of his n classmates demanded chocolates from him. But Roy wanted to give
chocolates only to his friends.
So, he told them to stand in a circle around him, where the 1st student stands next to the nth one. Then Roy will follow a strategy to distribute
the chocolates. He will start by giving chocolate to some person b, and will continue to give chocolate to every sth person. After someone receives chocolate,
s/he does not leave the circle.
Roy noticed the positions of his friends, and now he wants to choose b and s in such a way that, only and all of his friends get those chocolates.
Input Format
The first line of input contains 2 space separated integers, n and m, number of Roy's classmates and number of Roy's friends.The next line contains m space separated integers, the positions of Roy's friends.
Output Format
Output suitable b and s to execute Roy's plan. If no suitable answer exists, output "impossible" ( without the quotes ).
If there are multiple solutions, print any of them.
Constraints
1 ≤ n ≤ 10 9 1 ≤ m ≤ 10 6
m ≤ n
positions of Roy's friends will be given in increasing order.
相关文章推荐
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析
- C++实现汉诺塔算法经典实例
- PHP实现克鲁斯卡尔算法实例解析