Nowcoder Girl 2017题目集合详解

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

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.排列
本题主要的题意就是使i位置上的数不等于i,因此对数组data采用遍历的方法,当data[i]=i+1时需要对i上面的数字相邻位置进行交换,理论上有几个data[i]=i+1的情况就需要交换几次,但是这里有种特殊情况,就是当data[i]=i+1并且满足data[i+1]=i+2时,虽然有两个值满足要求,但是由于是相邻的只需要交换一次即可。需要对这种情况进行讨论。即用i(i<n)表示数组的下标遍历数组,当没有相邻数字满足的时候,就每出现一次data[i]=i+1,将结果加1,同时i+=1;如果出现相邻数字满足时,结果加1,同时i+=2;依次遍历,直到遍历完数组。
#-*-coding:utf-8-*-
n=int(raw_input())
data=map(int,raw_input().split())
i=0
ans=0
while(i<n):
    if(data[i]==i+1):
        if(i+1<n and data[i+1]==i+2):
            i+=2
            ans+=1
        else:
            i+=1
            ans+=1
    else:
        i+=1
print ans
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<n and sums<s):
    sums+=coin[k]
    k+=1
    ans+=1
for i in range(k,0,-1):
    if(sums-coin[i-1]>=s):
        sums-=coin[i-1]
        ans-=1
print ans
#求和应该从小到大加,然后减应该从大到小减
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<n;i++)
		{
			for(int j=0;j<5;j++)
				max_num[j]=Math.max(s[i][j],max_num[j]);
		}
		if(k==1)
		{
			for(int i=0;i<n;i++)
			{
				int temp=0;
				for(int j=0;j<5;j++)
				{
					temp+=s[i][j];
				}
				res=Math.max(temp, res);
			}
		}
		else if(k==2)
		{
			for(int i=0;i<n;i++)
			{
				for(int j=i+1;j<n;j++)
				{
					int temp=0;
					for(int h=0;h<5;h++)
					{
						temp+=Math.max(s[i][h], s[j][h]);
					}
					res=Math.max(temp, res);
				}
			}
		}
		else if(k==3)
		{
			for(int i=0;i<n;i++)
			{
				for(int j=i+1;j<n;j++)
				{
					for(int e=j+1;e<n;e++)
					{
						int temp=0;
						for(int h=0;h<5;h++)
						{
							temp+=Math.max(s[i][h], Math.max(s[j][h], s[e][h]));
						}
						res=Math.max(temp, res);
					}
				
				}
			}
		}
		else if(k==4)
		{
			for(int i=0;i<5;i++)
			{
				for(int j=i+1;j<5;j++)
				{
					int temp=0;
					for(int e=0;e<n;e++)
					{
						temp=Math.max(temp, s[e][i]+s[e][j]);
					}
					for(int h=0;h<5;h++)
					{
						if(h!=i && h!=j)
							temp+=max_num[h];
					}
					res=Math.max(res, temp);
				}
			}
		}
		else
		{
			for(int i=0;i<5;i++)
			{
				res+=max_num[i];
			}
		}
		return res;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int k=sc.nextInt();
		int[][] s=new int[n][5];
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<5;j++)
			{
				s[i][j]=sc.nextInt();
			}
			
		}
		System.out.println(solve(n,k,s));

	}

}
5.平方数

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

n=int(raw_input())
t=int(n**0.5)
print t*t
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]

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值