目录
派对
沫璃邀请她的朋友参加周末的派对。沫璃买了3种颜色的气球,现在她要有这些气球来装饰餐桌,每个餐桌只用恰好3个气球装饰,要求3个气球的颜色不能完全一样,可以是2种或者3种颜色。沫璃想知道这些气球最多能装饰多少张餐桌。
输入描述:
第一行一个数T(T<=100),表示数据组数。对于每组数据,第一行3个整数r,g,b,分别表示三种颜色的气球个数(0<=r, g, b<=2*10^9)
输出描述:
对于每组数据,输出一行,一个整数表示最多能装饰的餐桌数量。
输入例子1:
2
5 4 3
2 3 3
输出例子1:
4
2
我的代码(错误):
def solu(x):
m1 = min(x)
s1 = x.index(m1)
del x[s1]
x = [s-m1 for s in x]
m2 = min(x)
s2 = x.index(m2)
m3 = max(x)
s3 = x.index(m3)
if x[s3] >= m2*2:
return m1+m2
else:
return m1+m3/2
while True:
try:
T = input()
inp = []
for _ in range(T):
inp.append(map(int, raw_input().split(' ')))
for x in inp:
print solu(x)
except:
break
我的思路是先把三种气球里面的最少的那种颜色的数量m1找出来,然后从三个颜色的气球里面都取出m1个,用每个颜色取一个的方式,来算做桌子的数量,然后,将剩下的两种颜色的气球里,如果比较多的颜色的气球的数量大于比较少的颜色的气球的数量的两倍,就按比较少的气球颜色的数量为可做桌子的数量;如果小于,那么就那比较多的颜色气球的数量的一半作为可以做桌子的数量。提交后通过率百分之0。全错!
上面的思路错在,以三种单色作为考虑的切入点,但实际上如果想要数量最多,那么应该尽可能的让2种颜色的组合多起来才是王道,所以,思路从一开始就错了。
下面再看正确的思路,分为两步,第一步,找最多颜色气球的数量是否是其他两种颜色气球数量之和的二倍,如果是,就可以都组合成2:1的模式,让桌数增多,第二步,(最难理解的)如果最多颜色气球的数量小于其他两种颜色气球数量之和的二倍,应该:
res = (x[0]+x[1]+x[2])/3
为什么直接把所有的数相加除以三就行了呢?我百思不得其解,后来想通了,当最多颜色气球的数量小于其他两种颜色气球数量之和的二倍的时候,不容易想,我们考虑极端情况,假设有三种颜色红(最多),黄(次多),蓝(最少),如果最多颜色气球的数量等于剩下两种颜色气球数量的时候,我现在把红颜色数量除以3得到n1,那就是有n1组,黄颜色除以3得到n2,同理再得到n3,我这个时候,因为n1 = n2+n3,那我从(n2+n3)组里面每个里面每组取出1个颜色和n1组里的气球交换,就可以了!最后,n1+n2+n3,都是桌子数量了。如果n1>n2+n3,那么,我n1在组合完n2,n3后,再用势必会是单一颜色的,因为黄和蓝已经用完了!如果n1<n2+n3的时候,你想想,当n1和n2+n3相等的时候尚且可以保证交换,比他俩小的时候,肯定可以保证n1是桌子的数量,那么剩下的(n2+n3-n1)之间也一定是可以交换的,因为只要保证任意两种比剩下的一种大,就可以保证颜色岔的开。
(感性的理解思路,可能不是特别的清晰,但我也不知道怎么能表达的更具体了--||)
正确code:
def solu(x):
x = sorted(x)
if x[-1] >= 2*(x[0]+x[1]):
res = x[0] + x[1]
if x[-1] < 2*(x[0]+x[1]):
res = (x[0]+x[1]+x[2])/3
return res
while True:
try:
T = input()
inp = []
for _ in range(T):
inp.append(map(int, raw_input().split(' ')))
for x in inp:
print solu(x)
except:
break
赛马
茉莉有2n匹马,每匹马都有一个速度v,现在茉莉将马分为两个队伍,每个队伍各有n匹马,两个队之间进行n场比赛,每场比赛两队各派出一匹马参赛,每匹马都恰好出场一次。茉莉想知道是否存在一种分配队伍的方法使得无论怎么安排比赛,第一个队伍都一定能获的全胜,两匹马若速度不同,那么速度快的获胜,若速度一样,则都有可能获胜。
输入描述:
第一行一个数T(T<=100),表示数据组数。
对于每组数据,第一行一个整数n , (1<=n<=100)
接下来一行,2*n个整数,第i个整数vi表示第i匹马的速度, (1<= vi <= 1000)
输出描述:
对于每组数据,输出一行,若存在一种分配方法使得第一个队伍全胜输出YES,否则输出NO
输入例子1:
2
2
1 2 3 4
1
1 1
输出例子1:
YES
NO
我的思路(错误):
我想的比较简单,我的思路是,因为最终是分两组,而且两组的马数一样,,因为要判断是否可以判断第一个队伍都一定能获的全胜,那我就先把所有数从小到大排序,然后,找中间元素后,和将中间元素和它之前的元素做比较,如果比之前元素大,说明,后面的所有元素都比前面的元素大。如果相等,就将之前的元素向前移一位,中间元素向后移动一位,再比较,如果一直相等,就一直这样比较,直到出现不相等的时候,说明可以,如果所有元素都遍历完还没发现不相等,那就说明这列元素不可能。
def solu(x,inps):
inps = sorted(inps)
mid = len(inps)/2
if (inps[mid]>inps[mid-1]):
return 'YES'
if (inps[mid] < inps[mid-1]):
return 'NO'
if (inps[mid-1] == inps[mid]):
i = mid-1
j = mid
try:
while (inps[i] == inps[j]):
if i>=0:
i = i-1
if j < len(inps):
j = j+1
except:
return 'NO'
return 'YES'
while True:
try:
T = input()
inp = []
v = []
for _ in range(T):
inp.append(input())
v.append(map(int, raw_input().split(' ')))
for x, inps in zip(inp, v):
print solu(x, inps)
except:
break
上面的思路为什么错呢?其实感觉是没错,就是题意含糊,要求低的那组的最高值要比高的那组的最低值比较,哪怕是相等也不行,如果后者比前者大,那就是YES,否则是NO。
正确的code:
def solu(x,inps):
inps = sorted(inps)
mid = len(inps)/2
first = inps[mid:]
second = inps[:mid]
if first[0] > second[-1]:
return 'YES'
else:
return 'NO'
while True:
try:
T = input()
inp = []
v = []
for _ in range(T):
inp.append(input())
v.append(map(int, raw_input().split(' ')))
for x, inps in zip(inp, v):
print solu(x, inps)
except:
break
玫瑰花
有K种不同的玫瑰花,现在要摆放在N个位置上,要求每种颜色的花至少出现过一次,请问有多少种不同的方案数呢?,因为答案可能很大,你只需要输出它对772235取余后的结果.
输入描述:
输入只有1行,分别有两个整数N,K( 1 <= N <= 50000 , 1 <= K <= 30 )
输出描述:
输出一行表示答案
输入例子1:
3 2
输出例子1:
6
我是思路是:
分三种情况考虑呗,如果K=N,就是全排列,res = K!
如果K>N, 那就是花的种类比要放的位置多,那第一个位置有K个选择,第二个位置有K-1个选择,。。。依次类推,一共N个位置。
如果K<N,那就是要放的位置比花的种类多,那和上面的思路一样就行了。
这样想为啥错了呢?
网上查到的正确思路:
N>K:先保证N中有K个位置上一定是每一种颜色的花,然后N-K位置上随便排。 注意边界条件。
K>N:直接输出0,因为这样保证不了每种花至少出现一次。
N=K:输出1,
K=0或者N=0输出0.
但还是报错,只通过了20%。为啥呢?
while True:
try:
N, K = map(int, raw_input().split(' '))
res = 1
if K==0 or K==0:
print '0'
if K == N:
print res
if K > N:
res = 0
print res
if K < N:
for i in range(K,N+1):
res = res*i
s = long(772235)
res = res%772235
print res
except:
break