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]
相關文章
- XYCTF pwn部分題解 (部分題目詳解)
- Kotlin——集合詳解Kotlin
- 【Contest】Nowcoder 假日團隊賽1 題解+賽後總結
- 題解集合
- Redis有序集合詳解Redis
- Java集合詳解(二)Java
- Java集合詳解(三)Java
- 經典題目螺旋方陣的詳解
- Java集合詳解(一):全面理解Java集合Java
- JOISC2017 題解
- Girl Permutation
- java基礎詳解-集合Java
- 【Java集合】單列集合Collection常用方法詳解Java
- nowcoder Week Contest
- Linux 目錄詳解Linux
- linux目錄詳解Linux
- 集合劃分 題解
- JavaScript --- Map集合結構詳解JavaScript
- JavaScript — Map集合結構詳解JavaScript
- Redis 有序集合(zset)命令詳解Redis
- 題解目錄
- AndroidSDK的目錄詳解Android
- java集合學習(一):詳解ArrayListJava
- Java中的併發集合詳解Java
- windows臨時目錄詳解Windows
- LeetCode《買賣股票的最佳時機》系列題目,最詳解LeetCode
- 2024夢熊BeiJing集訓題目題解目錄
- Java 集合詳解 | 一篇文章解決Java 三大集合Java
- 題目 1841: [藍橋杯][2017年第八屆真題]發現環
- Java內功心法,Set集合的詳解Java
- echarts 柱狀圖 詳解與使用集合Echarts
- Java集合詳解(三):LinkedList原理解析Java
- Java集合詳解(五):Hashtable原理解析Java
- Java集合詳解(二):ArrayList原理解析Java
- Java集合詳解(三):HashMap原理解析JavaHashMap
- 搞懂 HashSet & LinkedHashSet 原始碼以及集合常見面試題目原始碼面試題
- Linux建立目錄 mkdir 詳解(全)Linux
- Java集合中List,Set以及Map等集合體系詳解(史上最全)Java