前一节体育课十二分钟跑跑寄了遂在自己笔记本上打的比赛。
一种等价类划分问题
模拟。可以使用字典完成。
注意审题,范围不包括m和n,以及要按数字和大小顺序输出。一开始还没注意输入输出格式。T1再次连交两发WA.
以后做题一上来一定不能急,仔细审题,确保签到题一次性对。
from collections import defaultdict
m,n,k=map(int,input().split(','))
a=defaultdict(list)
keys=set()
for i in range(m+1,n): t=str(i) s=0 for j in range(len(t)): s+=int(t[j]) if(s%k==0): a[s].append(i) keys.add(s)
keys=list(keys)
keys.sort()
for i in keys: print(",".join(map(str,a[i])))
dance
贪心。相邻两人组一组,差一定是最小的。
n,d=map(int,input().split())
a=list(map(int,input().split()))
flag=1
a.sort()
for i in range(0,2*n-1,2): if(a[i+1]-a[i]>d): flag=0 break
if(flag==1): print("Yes")
else: print("No")
洋葱
直接考虑每个方块的数字之和,周围一圈的和就是大方块减小方块。
n=int(input())
a=[]
for i in range(n): t=list(map(int,input().split())) a.append(t)
i=0
j=n-1
res=[]
while(i<=j): temp=0 for p in range(i,j+1): for q in range(i,j+1): temp+=a[p][q] res.append(temp) i+=1 j-=1
res.append(0)
ans=[]
for i in range(len(res)-1): ans.append(res[i]-res[i+1])
print(max(ans))
数的划分
dfs需要剪枝。为保证不重不漏,考虑从小到大搜,因此每次搜索的数不小于前一个数,同时不大于剩余所有数的平均数。
dp状态定义为i个数分为j组的方案数。由于每组均为正整数,考虑先每组置1,再将剩余的数分1-j组。
状态转移方程:\(dp[i][j]=\sum_{k=1}^j dp[i-j][k]\)
注意到\(dp[i][j]=\sum_{k=1}^{j-1} dp[i-j][k]\)
因此\(dp[i][j]=dp[i-1][j-1]+dp[i-j][j]\)
或者考虑选1或不选1.选1即为dp[i-1][j-1],不选1则可以把每组减1,依然符合条件,即为dp[i-j][j].
n,k=map(int,input().split())
ans=0
def dfs(step,cur,s): global ans if(s<0): return if(s==0 and step<k): return if(step==k): if(s==0): ans+=1 return for i in range(cur,s//(k-step)+1): dfs(step+1,i,s-i)
dfs(0,1,n)
print(ans)
n,k=map(int,input().split())
dp=[[0 for _ in range(k+1)]for _ in range(n+1)]#把i划分为j组的方案数
for i in range(1,n+1): dp[i][1]=1
for i in range(1,n+1): for j in range(2,k+1): if(i==j): dp[i][j]=1 elif(i>j): dp[i][j]=dp[i-1][j-1]+dp[i-j][j]
print(dp[n][k])
购物
好难的贪心。
考虑相同硬币数能够最多能够组成1-m的面值。下一次需要选取小于等于m+1面值的硬币,这样可以完全覆盖。一直选到能够覆盖到x面值。
x,n=map(int,input().split())
a=list(map(int,input().split()))
a.sort()
ans=1
if(n==0): print(-1)
elif(a[0]!=1): print(-1)
else: cur=1 while(cur<x): for i in range(n-1,-1,-1): if(a[i]<=cur+1): ans+=1 cur+=a[i] break print(ans)
排队
谁懂打开比赛题目列表发现T是一道之前老师布置的难题且没有尝试的救赎感。
没get到为什么标签是贪心。感觉更像升级版冒泡排序。
如果一个数与前面所有数的最大值与最小值都相差d以内,那么它一定可以到开头去。每一次都这么操作,把能够放到开头的元素存到缓存数组中并排序,如果没有就只放开头,并把当前数组加到答案数组末端。
n,d=map(int,input().split())
a=[]
for i in range(n): t=int(input()) a.append(t)
check=[1]*n
ans=[]
maxm=a[0]
minm=a[0]
while(sum(check)!=0): i=0 qaq=[] maxm=0 minm=0 while(i<n): if(check[i]==1): if(len(qaq)==0): check[i]=0 qaq.append(a[i]) maxm=a[i] minm=a[i] else: if(a[i]>=maxm): maxm=a[i] elif(a[i]<=minm): minm=a[i] if(a[i]>=maxm-d and a[i]<=minm+d): qaq.append(a[i]) check[i]=0 i+=1 qaq.sort() ans.extend(qaq)
for i in ans: print(i)