Nowcoder Girl 2017题目集合详解

        这是对牛客网举办的Nowcoder Girl的编程比赛的题目做一个题解。

1.勇气获得机

Nowcoder Girl 2017题目集合详解_第1张图片

这题主要是为了判断奇偶性,一种逆序的思维,根据倒序的方法求出结果翻转之后便是正确答案。

代码如下:

#-*-coding:utf-8-*-
n=int(raw_input())
s=''
while(n>0):
    if(n%2==0):
        s+='G'
        n=(n-2)/2
    else:
        s+='N'
        n=(n-1)/2
print s[::-1]

2.排列

Nowcoder Girl 2017题目集合详解_第2张图片
本题主要的题意就是使i位置上的数不等于i,因此对数组data采用遍历的方法,当data[i]=i+1时需要对i上面的数字相邻位置进行交换,理论上有几个data[i]=i+1的情况就需要交换几次,但是这里有种特殊情况,就是当data[i]=i+1并且满足data[i+1]=i+2时,虽然有两个值满足要求,但是由于是相邻的只需要交换一次即可。需要对这种情况进行讨论。即用i(i
#-*-coding:utf-8-*-
n=int(raw_input())
data=map(int,raw_input().split())
i=0
ans=0
while(i

3.打车

Nowcoder Girl 2017题目集合详解_第3张图片

    这题的思路比较明确就是先对拥有的硬币进行排序,因为需要的硬币个数越多越好,所以先从小到大进行加,但是当和大于s便停止加;又因为题目要求不能拿掉任意一个硬币还大于s;所以此时还需要遍历一遍已经加过的硬币,为了保证数量是最多的,应该从大到小遍历,避免减去一个稍微大的可以满足题目最终要求,但如果从小到大减则需要减大于1个小的,那么就使得结果不是最优解,因此应该从大到小遍历,判断拿掉当前硬币,是否还大于s,如果是则减去当前硬币,否则继续往前遍历。

# -*-coding:utf-8 -*-
n,s=map(int,raw_input().split())
coin=map(int,raw_input().split())
coin.sort()
sums=0
k=0
ans=0
while(k=s):
        sums-=coin[i-1]
        ans-=1
print ans
#求和应该从小到大加,然后减应该从大到小减

4.勇敢的妞妞

Nowcoder Girl 2017题目集合详解_第4张图片
        因为每一种装备都有五个属性,所以有一种情况很明确,就是当选取的装备件数大于等于5件的时候,只需要将每种属性的最大值相加即可。于是只需要讨论k<5的情况:当k=1只需要遍历求每种装备的属性和,取最大值即可;当k=2时,只需要使用i,j变量来控制任意两个装备,然后只需要将两者的每个属性的较大值相加即可,求出具有最大值的两两组合;当k=3,则利用i,j,h来控制三种装备,思路与k=2时差不多;重点是k=4,如果还用之前的思路,则必然会超时,这时候换种思路,不再控制装备,而是控制属性,因为属性只有五种,所以对时间影响不大,总的属性有五种,这时候需要选择四个装备,如果是五个装备,那么只需求每种属性的最大值即可,那么四个,则需要将其中的两个属性绑定在一起,另外三个则是求最大值,这样才能保证得到的是最大值,那么绑定的如何求呢?即遍历五种属性,外循环控制一种属性,内循环控制与之绑定在一起的属性,然后通过最内循环来控制装备,这样可以得到那种装备的那两种属性和是最大的,然后最内循环还需要加上剩下三种属性的最大值,并与结果比较大小,取大值。

首先是Python代码,该代码只能AC90%。

#-*-coding:utf-8-*-
def solve(n,w,s):
    max_num=[0 for i in range(5)]
    for i in range(n):
        for j in range(5):
            max_num[j]=max(s[i][j],max_num[j])
    res=0
    if(w==1):
        for i in range(n):
            temp=0
            for j in range(5):
                temp+=s[i][j]
            res=max(res,temp)
    elif(w==2):
        for i in range(n):

            for j in range(i+1,n):
                temp = 0
                for k in range(5):
                    temp+=max(s[i][k],s[j][k])
                res=max(res,temp)
    elif(w==3):
        for i in range(n):
            for j in range(i+1,n):
                for k in range(j+1,n):
                    temp=0
                    for h in range(5):
                        temp+=max(s[i][h],s[j][h],s[k][h])
                    res=max(temp,res)
    elif(w==4):#有一个装备肯定有两项技能和比较高,贪心
        for i in range(5):
            for j in range(i+1,5):
                temp=0
                for k in range(n):
                    temp=max(temp,s[k][i]+s[k][j])
                for h in range(5):
                    if(k&i==0 and k&j==0):
                        temp+=max_num[h]
                res=max(temp,res)
    else:
        for i in range(5):
            res+=max_num[i]
    return res
if __name__ == '__main__':
    n,k=map(int,raw_input().split())
    s=[]
    for i in range(n):
        w=map(int,raw_input().split())
        s.append(w)
    print solve(n,k,s)

然后根据以上同样的思路写的Java代码,AC了。

import java.util.*;;

public class Main {
	public static int solve(int n,int k,int[][] s)
	{
		int res=0;
		int[] max_num=new int[5];
		for(int i=0;i

5.平方数

Nowcoder Girl 2017题目集合详解_第5张图片

        本题只需要将输入的开平方取整,然后再平方即可:

n=int(raw_input())
t=int(n**0.5)
print t*t

6.美丽的项链

Nowcoder Girl 2017题目集合详解_第6张图片
        本题是一个动态规划的题,这个题目就类似于凑钱的题目,只不过相当于给每种钱都添加了个数,而不是单纯的一个或0个;dp[i][j]表示前i种水晶宝珠能凑成j颗的方法数,当前i的宝珠颗数为li~ri,所以那么为了凑齐j颗,需要保证前i-1种宝珠需要凑齐多少颗(利用j与li、ri进行简单计算求得),求得一个范围都可以,那么只需要加上前i-1宝珠所有能满足需求的方案数。代码如下:

#-*-coding:utf-8-*-
l=[]
r=[]
n,m=map(int,raw_input().split())
for i in range(n):
    li,ri=map(int,raw_input().split())
    l.append(li)
    r.append(ri)
ways=[[0 for i in range(m+1)] for j in range(n)]
for i in range(l[0],r[0]+1):
    ways[0][i]=1
for i in range(1,n):
    for j in range(m+1):
        left=max(0,j-r[i])
        right=max(0,j-l[i])#当前珠宝种类i的个数有li~ri个,所以前i种珠宝要凑成j个珠宝,则需要使得前i-1种凑成的珠宝数需要在left~right之间,
                            # 那么第i种才能够补上。
        for k in range(left,right+1):
            ways[i][j]+=ways[i-1][k]  #ways[i][j]表示i种珠宝凑成j个珠宝的方法数,way[i-1][k]为前i-1种珠宝凑成k个的方法数

print ways[n-1][m]

你可能感兴趣的:(算法题题解)