思路是很简单的,就是以时间为主线,在当前时刻,先统计出所有该时刻提出的idea

然后以PM为类别分组这些idea即代码中的group

然后计算出每个PM最想先实现的idea,记录在IdeaPriority中

然后就是遍历每个程序员,只要程序员在该时刻空闲,就从IdeaPriority中按题目要求选出一个idea给其完成

遍历完每个程序员后也就是说在当前时刻遍历完了所有程序员,然后时刻+1,

继续循环,即统计出所有这新时刻下提出的idea,,,,,,,,,,

下面是python 版本,由于耗时只通过了60%,所以还是用C快一下,有时间再写一个c版本的吧!!!

N,M,P = [int(e) for e in input().split()]
idea = []
for i in range(P):idea.append([int(e) for e in input().split()]+[i])
idea.sort(key = lambda x:x[1])finsh = 0                       #程序员完成的idea个数
NoTime = 1                      #当前时刻
last = 0                        #上一次idea进入的下标
Program = [0 for _ in range(M)] #程序员直到空闲的时刻
NoTimeIdea = []                 #当前时刻待解决的idea
result = {}                     #结果
group = {}                      #当前时刻各个程序员提出的idea集合while finsh<P:#当前时刻待解决的所有ideafor i in range(last,P):if idea[i][1]==NoTime:if idea[i][0] not in group:group[idea[i][0]] = [idea[i]]else:group[idea[i][0]].append(idea[i])if i==P-1:last = Pelse:last = ibreak#选出每个产品经理最想实现的ideaIdeaPriority = []for j in group.keys():group[j].sort(key = lambda x:(-x[2],x[3],x[1]))IdeaPriority.append(group[j][0])#给每个程序员选出需要解决的ideafor i in range(M):IdeaPriority.sort(key = lambda x:(x[3],x[0]))if Program[i]<=NoTime and len(IdeaPriority)!=0:Program[i] = NoTime+IdeaPriority[0][3]result[IdeaPriority[0][4]] = Program[i]j = IdeaPriority[0][0]index = IdeaPriority[0][4]#从IdeaPriority中删除已经解决的ideaIdeaPriority.pop(0)#从group中删除已经解决的ideafor p in range(len(group[j])):if group[j][p][4]==index:group[j].pop(p)if len(group[j])==0:del group[j]else:group[j].sort(key = lambda x:(-x[2],x[3],x[1]))IdeaPriority.append(group[j][0])breakfinsh+=1NoTime+=1
for i in range(P):print(result[i])

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

此题的关键是要读出如下信息:

因为一些特殊的原因,不会出现一个查询的用户区间完全覆盖另一个查询的用户区间

即我们可以先给整个查询按照第一个字段排序(即待查询用户的起始标号),这里采用升序

排序后注意:

只会出现如下区间错位:

即类如[2,6] [4,8]

而不会出现:

所以经过排序后,假设当前这一组的查询区间为 [L_now, R_now],紧挨着其下一组是[L_next, R_next]

那么一定是:

L_now<L_next<=R_now

R_now<R_next

好了,下面我们进入正题:

首先我们使用一个字典来记录当前待查询区间下每一个喜好值对应的人数

-------------------------------------------------------------------------------------------------------------------------------------

举例:有一组喜好值

1,4,3,5,5,7,3,5,9,10

可以看到喜好值有1,3,4,5,6,7,9,10这几种:

假设当前查询的区间是[2,6]即4,3,5,5,7那么字典中记录的应该是:

1:0

3:1

4:1

5:2

6:0

7:1

9:0

10 : 0

那么我们再看一下当前待查询区间要查询的喜好值,比如说是5,那我们从字典中找到对应的key下的value即可这里是2

---------------------------------------------------------------------------------------------------------------------------------------

所以我们就将待查询的数据一组组输入,然后统计该区间内的各个喜好值,最后对应查询即可

问题转化为怎么统计该区间内的各个喜好值,本题的巧妙之处就在于这里的动态规划:

假设现在我们统计的是下一组(图中下面一个条形框)

由于我们上一组已经统计过了(图中上面一个条形框),可以看到其实黄色部分是可以利用的,不用在重新统计,换句话说:

丢弃蓝色,保留黄色,再多统计一下灰色

这里采用的方法是:

遍历蓝色中的每一个元素,在字典中使该元素减一

遍历灰色中的每一个元素,在字典中使该元素加一

可以想象结果就是:

丢弃蓝色,保留黄色,多统计了一下灰色

代码如下:

_ = input()
arr = []
d = {}
for e in input().split():arr.append(int(e))d[int(e)] = 0n = int(input())
temp = []
for i in range(n):e = input().split()e[0] = int(e[0])-1e[1] = int(e[1])-1e[2] = int(e[2])temp.append(e+[i])
temp.sort()result = []
left = 0
right = -1
arr[0] = 1
for i in range(n):tempList = temp[i]left_interval = tempList[0] - leftright_interval = tempList[1] - rightfor l in range(left_interval):d[arr[left+l]]-=1for r in range(right_interval):d[arr[right+r+1]]+=1if tempList[2] in d:result.append([d[tempList[2]],tempList[3]])else:result.append([0,tempList[3]])left = tempList[0]right = tempList[1]result = sorted(result,key = lambda x:x[1])
for i in range(n):print(result[i][0])

代码中的d就是字典

 for l in range(left_interval):d[arr[left+l]]-=1

就是天蓝色

for r in range(right_interval):d[arr[right+r+1]]+=1

就是灰色

 if tempList[2] in d:result.append([d[tempList[2]],tempList[3]])else:result.append([0,tempList[3]])

就是记录一下当前这一组的查询结果

这里的tempList[3]只是为了便于结果按顺序输出,因为开头排了一下序,所以顺序是乱的,所以多加了一个索引即:

temp.append(e+[i])中的[i]

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

该题的关键在于要准确找到到底一开始是哪个房间的人全部出来了(代码中的start就是该房间的索引)

根据题意我们很容易就可以确定一定是分配后所有房间的最小值,

假设最小值只有一个的时候,毫无疑问一开始就是这个房间的人全部出来了,

如果最小值有多个那么怎么确定呢?这也是本题的关键和难点所在:

这里就要结合题中给出的x进行综合判断得出了,现分成以下情况进行讨论:

当最小值的索引全在x的左边时:

那么start就是这些最小值集合的最后一个最小值的索引

当最小值的索引全在x的右边时:

那么start就是这些最小值集合的最后一个最小值的索引

当最小值的索引部分在x的右边部分在x左边时:

那么start就是左半部分最小值集合中最后一个元素的索引

总结来说就是:

先看x左半部分有没有元素,有的话就选左半部分最后一个元素作为start

没有的话(全在右面的话)我们就选最后一个元素索引作为start

至于为什么这样,稍微结合题意推断一下就可知道了,其中的逻辑道理倒不是很难,难就难在想不到这个解题的点。

确定了start那就好办了,同时我们也知道了最小值,这个最小值其实就代表了进行了几轮,代码中mintemp就是指的这里的最小值,进行了mintemp这么多轮,那么每个房间肯定都加了mintemp个人,所以先减去mintemp,同理start就出去了n*mintemp个人。

整轮考虑完了以后,我们再来看最后一个没有走完整轮的过程:

,,,,,,,,,startcur,,,,,,,,,,,,,end,,,,,,,,,,,,,,,,,,,,,,,

其实就是,,,,,,,,,,,,,这部分房间都再多减一就是对应其原来房间人数啦

需要注意的是有可能是下面这种情况:那么再多减一的房间就是下面红色的部分

,,,,,,,,,,,,,,,,,,end,,,,,,,,,,,,startcur,,,,,,,,,,,

代码中

while startcur!=x:startcur = (startcur+1)%nresult[startcur]-=1result[start]+=1

就是对应这部分,可以看到startcur就是每次加一,不断向前搜索房间,知道遇到end

当然了我们最开始确定的start这个房间要单独特殊处理,其原来的人数应该是在n*mintemp基础上继续加人数,加多少呢?那就是看最后这次搜索的房间数啦,即result[start]+=1

最后附上全部代码:

n,x = [int(e) for e in input().split()]
x = x-1
mintemp = 10**9
home = []
homemin = []
for i,e in enumerate(input().split()):e = int(e)home.append(e)if e<mintemp:homemin = []homemin.append(i)mintemp = eif e==mintemp:homemin.append(i)
i = 0
while i<len(homemin) and homemin[i]<=x:i+=1
start = homemin[i-1]
startcur = start
result = [e-mintemp for e in home]
result[start] = n*mintemp
while startcur!=x:startcur = (startcur+1)%nresult[startcur]-=1result[start]+=1
for e in result:print(e,end=' ')

说明一点:

巧妙之处在于

while i<len(homemin) and homemin[i]<=x:i+=1
start = homemin[i-1]

这里的代码作用就是在找start

可以看到其其实就是在搜索x左面元素集合的最后一个,即i-1就是最后一个元素

如果左边没有,那么i=0,i-1=-1,恰好选整个最小值集合的最后一个值作为start,满足我们上面的分析

这里也就是在编程方面绕了一下,最注意的逻辑还是上面我们分析的

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

这题咋一看挺难的,其实是非常简单的,关键是看有没有分析出其中的关键点。

首先6个面转,其实就可以简化看做是三个面在转,比如我们考虑前,上,右

然后在这三个面中我们可以进一步简化:

比如说单看前面这一个面,其有2层即上下层,上层可以左右转90度,下层可以左右转90度,咋一看是4种情况,其实就是2种即上层右转90就相当于下层左转90,所以我们只要考虑一层就可以啦,比如说只考虑上层左转还是右转这2种情况,上右面也是如此。

综上所述,每一步中一共有3*2=6种情况,然后深度遍历即可

链接:https://www.nowcoder.com/questionTerminal/7f51d0abdfdf44d2a2a777ea35124eb2
来源:牛客网def compute(A):return A[0]*A[1]*A[2]*A[3] + A[4]*A[5]*A[10]*A[11] + A[6]*A[7]*A[12]*A[13] + A[8]*A[9]*A[14]*A[15] + A[16]*A[17]*A[18]*A[19] + A[20]*A[21]*A[22]*A[23]def DS(A,i):if i == 0:return
#六种情况进行旋转,每次转动12个。A1 = A.copy()A1[1], A1[3],A1[7], A1[13], A1[17], A1[19],A1[21],A1[23],A1[8], A1[9],A1[14],A1[15] = A1[7], A1[13], A1[17], A1[19],A1[21],A1[23], A1[1], A1[3],A1[14], A1[8],A1[15],A1[9]res.append(compute(A1))DS(A1,i-1)A2 = A.copy()A2[1], A2[3],A2[7], A2[13], A2[17], A2[19],A2[21],A2[23],A2[8], A2[9],A2[14],A2[15] = A2[21],A2[23], A2[1], A2[3], A2[7], A2[13], A2[17],A2[19],A2[9], A2[15],A2[8],A2[14]res.append(compute(A2))DS(A2,i-1)A3 = A.copy()A3[4], A3[5], A3[6], A3[7], A3[8], A3[9], A3[23], A3[22],A3[0], A3[1], A3[2], A3[3] = A3[6], A3[7], A3[8], A3[9], A3[23], A3[22], A3[4], A3[5],A3[2], A3[0], A3[3], A3[1]res.append(compute(A3))DS(A3,i-1)A4 = A.copy()A4[4], A4[5], A4[6], A4[7], A4[8], A4[9], A4[23], A4[22],A4[0], A4[1], A4[2], A4[3] =  A4[23], A4[22], A4[4], A4[5], A4[6], A4[7], A4[8], A4[9],A4[1], A4[3], A4[0], A4[2]res.append(compute(A4))DS(A4,i-1)A5 = A.copy()A5[2], A5[3], A5[8], A5[14], A5[17], A5[16], A5[11], A5[5],A5[6], A5[7], A5[12], A5[13] = A5[8], A5[14], A5[17], A5[16], A5[11], A5[5], A5[2], A5[3], A5[7], A5[13], A5[6], A5[12]res.append(compute(A5))DS(A5,i-1)A6 = A.copy()A6[2], A6[3], A6[8], A6[14], A6[17], A6[16], A6[11], A6[5], A6[6], A6[7], A6[12], A6[13] =  A6[11], A6[5], A6[2], A6[3], A6[8], A6[14], A6[17], A6[16], A6[12], A6[6], A6[13], A6[7]res.append(compute(A6))DS(A6,i-1)i += -1row= [int(i) for i in input().strip().split()]
res = [compute(row)]
i = 5
DS(row,i)
print(max(res))

【编码题】字符串S由小写字母构成,长度为n。定义一种操作,每次都可以挑选字符串中任意的两个相邻字母进行交换。询问在至多交换m次之后,字符串中最多有多少个连续的位置上的字母相同?

思路就是遍历每一个字母,统计其在M步内所能构成的最大长度

在计算具体某一个字母下的最大长度时,应用动态规划:

利用该字母一共出现了6次,那么先计算每两个组合在一起的所有情况用到的最小步数,然后再动态考虑3个组合在一起的所有情况用到的最小步数,然后再动态考虑4个组合在一起的所有情况用到的最小步数,,,,,,等等

def Count(g,step):n = len(g)minstep = float('inf')dp = [[0 for _ in range(n)] for _ in range(n)]if n==1:return 1#所有2个连续相连所需要的互换次数for i in range(n-1):dp[i][i+1] = g[i+1]-g[i]-1minstep = min(minstep,dp[i][i+1])if minstep>step:return 1elif minstep==step:return 2else:#接着考虑3个连续的所有情况for i in range(2,n):minstep = float('inf')for j in range(n-i):row = jcol = j+i# 这里较难理解,假设显现考虑这样一个情况:# 12,,,,,,,,56#,,,,是中间部分,即dp[row+1][col-1]#那么假设中间部分排列好后左面是q,右面是p#那么本轮移动12 和56 就共需要q-12-1 和56-p-1#化简后就是56-12+q-p-2,假设12和56的坐标是row,col#可以得到 col-row-2 = p-q 所以q-p-2 = row-col#其中56-12就是g[col]-g[row] 所以56-12+q-p-2 = g[col]-g[row]-(col-row)dp[row][col] = dp[row+1][col-1]+g[col]-g[row]-(col-row)minstep = min(minstep,dp[row][col])if minstep>step:return iif minstep==step:return i+1return nS,m = [e for e in input().split()]
m = int(m)
group = {}for i,s in enumerate(S):if s not in group:group[s] = [i]else:group[s].append(i)result = 0
for key in group.keys():result = max(result,Count(group[key],m))
print(result)

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

此题是一个动态规划问题,所以关键在于找到递推式,分析如下:

假设第一次到达i这个房间的时候,其是第一次(奇数次),故下一步一定是返回到i之前的房间,经过一定步骤的时候再次回到i房间的时候,此次是偶数次,按照规则移动到下一个房间即i+1,此时对于i+1房间来说,其是第一次,又返回到i+1之前的房间,周而复始,,,,,,,,,,,,,,,,

通过上面的总结我们可以得到如下结论:

就拿第一次到达i房间来说,其先返回之前的某个房间,然后经过一系列步骤后再次回到i房间,注意此时i之前的所有房间被经过的次数都应该是偶数次,因为只有偶数次后,其才会向后走,然后一步步再次回到i

其实明白了这个规律,就好办了,现在假设dp[i]表示第一个房间到第i个房间所用的步数

f(i,j)表示第i房间到第j个房间所用的步数(注意这里所考虑的情况是当前i房间被访问的次数是奇数次)

home 是一个列表,保存的就是输入的第二行数据即房间之间的穿梭信息pi

所以比较容易得到:假设房间号i<=j

dp[i] = dp[j]+f(j,i) 进而可得f(j,i) = dp[i]-dp[j]

现在我们来看动态规划部分:即找dp[i]和dp[i-1]的关系式

dp[i] = dp[i-1] +f(i-1,i) = dp[i-1]+1+f(home[i-1],i-1)+1 = dp[i-1]+1 +dp[i-1]-dp[home[i-1]]+1=2dp[i-1] - dp[home[i-1]]+2

好啦,得到递推式:

dp[i]  = 2dp[i-1] - dp[home[i-1]]+2

分析结束

最后给一下全部代码:

n = int(input())
home = [int(e)-1 for e in input().split()]
dp = [0 for _ in range(n+1)]
dp[1] = 2
for i in range(2,n+1):dp[i] = 2*dp[i-1] - dp[home[i-1]]+2
print(dp[n]%1000000007)

注意:按照一般思路来说应该从i=1即第二个房间开始递推,而这里是从i=2即第三个房间开始的

那是因为:

比如看题目中给出的那个例子:

2

1 2

那么我们在求dp[1] 的时候会用到home[0] = 1 即dp[1] 所以要从第三个房间开始的

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

此题比较简单,就是从左到右遍历每一个字母,以其为起点(假设当前起点为i)进行记录a和b的个数,当两者个数同时达到m上限时停止,此时以i为起点在m步操作数限制的情况下所能得到的最大长度就是遍历过的总长度。

下面用队列来实现这一过程:

当队列中a的个数和b的个数都大于m时我们才考虑出队列情况,否则都是进队列

当两者都达到m时,若当前待进队列的元素是a时,我们就让队首出一个a,当然了如果队首是b就一直出队列

若当前待进队列的元素是b时,道理同样

全部代码:

n,m = [int(e) for e in input().split()]
Str = input()
result = 0
a_count = 0
b_count = 0
q = []
for e in Str:if e=='a':a_count+=1if e=='b':b_count+=1if a_count>m and b_count>m:if e=='a':while True:if q[0]=='a':q.pop(0)breakq.pop(0)b_count-=1a_count-=1else :while True:if q[0]=='b':q.pop(0)breakq.pop(0)a_count-=1b_count-=1q.append(e)result = max(result,len(q))
print(result)

头条算法题:产品经理,程序员任务调度、用户喜好值算法等等相关推荐

  1. Java数据结构与算法(九)-程序员常用的10中算法

    本章目录 第14章 程序员常用的10中算法 14.1 二分查找算法(非递归) 14.1.1 二分查找算法(非递归)介绍 14.2 分治算法 14.2.1 分治算法介绍 14.2.2 分治算法最佳实践- ...

  2. 悲哀!面试现场,简单几道java算法题,90%程序员没写出来

    这两天小编逛论坛的时候发现一个很有意思的事情,就是一位互联网公司的面试官分享的,他们最近想招一批java的实习生,所以他们的面试题并不难,但是前来面试的人,却很多都挂在了几道算法题上,要么就是逻辑不严 ...

  3. 惊!面试现场,简单几道java算法题,90%程序员没写出来

    近几个月很多大学实习生离校找实习工作去了,本以为自己很值钱,实际上发现自己并不值钱,想象着自己能赚很多钱了,结果只能拿到一点微薄的工资,很多人会怪公司给的少,但是你有没有想过,你自己的技术值多少钱?你 ...

  4. java算法题走楼梯,程序员必学算法「动态规划」:爬楼梯(完全背包解法)

    通知:我将公众号文章和学习相关的资料整理到了Github :https://github.com/youngyangyang04/leetcode-master,方便大家在电脑上学习,可以fork到自 ...

  5. 100%的程序员都想挑战的算法趣题!| 码书

    计算机的世界每天都在发生着深刻的变化.新操作系统的发布.CPU性能的提升.智能手机和平板电脑的流行.存储介质的变化.云的普及--这样的变化数不胜数. 在这样日新月异的时代中,"算法" ...

  6. 我敢打赌,这是98%的程序员都想挑战的算法趣题!

    计算机的世界每天都在发生着深刻的变化.新操作系统的发布.CPU性能的提升.智能手机和平板电脑的流行.存储介质的变化.云的普及--这样的变化数不胜数. 在这样日新月异的时代中,"算法" ...

  7. 100% 的程序员都想挑战的算法趣题!

    作者 | 图小敏 计算机的世界每天都在发生着深刻的变化.新操作系统的发布.CPU性能的提升.智能手机和平板电脑的流行.存储介质的变化.云的普及--这样的变化数不胜数. 在这样日新月异的时代中,&quo ...

  8. 从产品与程序员打架事件,谈谈需求管理的沟通能力

    原标题:从产品与程序员打架事件,谈谈需求管理的沟通能力 昨天一个平安科技内部两名员工打架的视频在互联网圈里疯狂,据传打架原因是产品经理给开发人员提了一个需求:要求app的主体颜色可以随着用户手机壳颜色 ...

  9. 程序员必须唱我哪些算法?

    为了让你对数据结构和算法能有个全面的认识,我画了一张图,里面几乎涵盖了所有数据结构和算法书籍中都会讲到的知识点. 这里面有10个数据结构:数组.链表.栈.队列.散列表.二叉树.堆.跳表.图.Trie ...

最新文章

  1. 《中国人工智能学会通讯》——9.21 基于任务规划的资源卫星智能管控模式
  2. C++实现的简单vector
  3. 微信小程序——获取所有资讯接口数据
  4. Python的初级语法
  5. 【数据结构与算法-2】链表
  6. 适用于MongoDB和Mongometer的SpiderMonkey至V8
  7. SAP License:后SAP ECC 6.0 时代
  8. [转载] 用pandas或numpy处理数据中的空值(np.isnan()/pd.isnull())
  9. 雷电模拟器 脚本_精灵盛典辅助雷电模拟器使用教程
  10. windows上java调用gdal.jar报错
  11. lwip协议栈源码分析之pbuf
  12. java 自动化测试_java写一个自动化测试
  13. vue插件大全汇总,你要的都这里,赶紧收藏下!
  14. FPGA综合系统设计(四):串口控制的DDS信号发生器
  15. EXTREME 设备操作手册
  16. Lipschitz条件
  17. 基于Trie树进行拆分字符串变成拼音音节(二):字符串拼音拆分
  18. 【博主推荐】html好看的邀请函(附源码)
  19. Django分页,过滤:
  20. 腾讯小程序服务器忙,使用腾讯云助手小程序管理腾讯云服务器

热门文章

  1. 1-Windows环境安装ARM DS-5
  2. mysql_时间段维度统计,关于MongoDB时间格式转换和时间段聚合统计的用法总结
  3. 营销型网站建设前期策划的意义
  4. draggable拖拽组件的使用
  5. 最大公约数Stein算法之verilog实现
  6. makefile 之 subst
  7. 研发,CEO、CIO选择了微软系
  8. Canvas画圆形刻度表
  9. 互联网趋势其实很浮夸
  10. 邮件信封背景设计模板素材推荐 精品 小众