USACO3.2题目简析

chunlvxiong的博客


T1:Factorials

  题意:输出N!最后非零位(1≤N≤4220)。

  首先你可以很快算出N!的末尾0的个数(即1到N的5的因子个数,记这个数为x)。然后你可以理解为求N!/(2^x)/(5^x) % 10的值。

  这样你就可以以O(N)的时间复杂度计算出这个值。

T2:Stringsobits

  题意:求出第i个长度为N(1≤N≤31)且这个二进制数中1的个数小于等于L(L<=N)的数(允许前导0)。

  用dp[i][j]表示长度为i,1的个数≤j的数的个数,则dp[i][j]=dp[i-1][j-1](放1)+dp[i-1][j](放0)。初始:dp[0][i]=1

  输出部分操作如下,从高位到低位操作,假设当前位数为x,还能放y个1,还需K个长度为N的且二进制数中1的个数小于等于L的数:

  如果dp[x-1][y]>=K,那么说明这一位应该放0,然后继续操作x-1位。

  如果dp[x-1][y]<K,那么说明这一位应该放1,然后K-=dp[x-1][y],然后y--(能放1的个数减少)。

  这样逐位确定即可。注意K的最大值为2^32会超过int。时间复杂度O(N*L)。

T3:Spinning Wheels

  题意:有5个水车,水车的角度为0..359,每个水车有一个速度,也有几个缺口。问最少多少s时,有一个角度所有水车都是缺口。若不存在这样的时刻,输出none。

  首先答案肯定是<360的,因为第360时刻与第0时刻的结果是一样的。

  那么你考虑如何验证一个时刻是否有一个角度所有水车是缺口,可以开一个标记数组进行统计,对于该时刻若某个角度当前水车是缺口,那么++,最后如果标技数组中有一个角度的值为5,说明该时刻有一个角度所有水车是缺口。

  这样做的时间复杂度是O(360^2)的,可以A掉此题。注意不要忘记0时刻也是可能的情况。

T4:Feed Ratios

  题意:有三种不同的混合饲料(每种配法都包含3种饲料),以及目标饲料,求如何将多少包这三种混合饲料混合可以得到多少包目标饲料。(每种混合饲料和目标饲料中3种饲料的数量均为<100的非负整数,同时保证每种混合饲料最多用100包)

  爆搜即可,时间复杂度O(100^3)。注意0的情况。

T5:Magic Squares

  题意:给出一个魔板,初始状态为1 2 3 4,记为{1,2,3,4,5,6,7,8}。有三种操作:“A”:交换上下两行;“B”:将最右边的一列插入最左边;“C”:魔板中央四格                                                                       8 7 6 5

  给定一个目标状态,求初始状态到目标状态最少所需操作数以及相应的操作步骤(字典序最小)。

  很容易想到广搜,总的状态数为8!种,并不多,因此广搜是可行的。关键问题在于如何判重。如果开一个8^8的标记数组,会MLE(得益于USACO的16M内存)。

  判重实际上就是算一个序列是第几个全排列,以6 5 8 4 3 7 2 1为例进行分析:

  第一个位置先前可以放1~5,所以先前已经有5*7!个全排列了。

  第二个位置先前可以放1~4,所以先前已经有4*6!个全排列了。

  第三个位置先前可以放1、2、3、4、7,所以先前已经有5*8!个全排列了。

  ……

  所以判重计算方法为Σ(8-i)!*(a[i]-1-先前比a[i]小的数的个数)。--注:这里计算这个复杂度是O(8^2)的,不是很理想,可以利用线段树优化到O(8log8),但是还是不写的好。

  另类判重方法:map判重,hash判重(找一个比8!大的素数)。

T5:Sweet Butter

  题意:有N头奶牛(1≤N≤500),P个牧场(1≤P≤800),C条双向道路(1≤C≤1450)。给出每头奶牛所在的牧场编号,求出令所有奶牛聚到同一个牧场所有奶牛所走的距离总和的最小值。

  由于是稀疏图,所以暴力穷举每个牧场作为集合牧场,然后跑spfa(或者堆优化的dijkstra)一遍,再计算出奶牛所走的距离总和,更新最小值即可。

转载于:https://www.cnblogs.com/chunlvxiong/p/7404228.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值