SRM 697 Div 2: 250分题目和500分题目代码

 刚刚完成了topcoder上面的SRM 697 Div 2 的比赛。这次比赛的题目应该说中规中矩,只要有一定的数学基础,解答起来相当简单。第一题是能否组成三角形的问题,非常简单就解决了,Challenge的时候,看到有人通过遍历来做,感到十分震惊。但是看题目中给出的数据范围确实比较小,所以这样解答也没问题。第二题用数学知识来解答的话,就是一个判断矩阵是否正定的问题,求解起来也相当容易,但是由于没有顾及到python 2中求两个整数的商时,会返回一个整形,而不是一个小数,因此最后在system test的时候,有几个样例没有通过。

* 250分题目*
Problem Statement

You have three sticks. Their current lengths are a, b, and c. You can shorten each of those sticks arbitrarily. Your goal is to produce three sticks with the following properties:

  1. The length of each stick is a positive integer.
  2. The three sticks can be used to build a triangle. The triangle must be non-degenerate. (I.e., it must have a positive area.)
  3. The perimeter of the triangle must be as large as possible.

You are given the ints a, b, and c. Compute and return the largest possible perimeter of the triangle constructed from your three sticks.
Definition:

Class   TriangleMaking
Method  maxPerimeter
Parameters  integer , integer , integer
Returns integer
Method signature    def maxPerimeter(self, a, b, c)
(be sure your method is public)

Limits

Time limit (s)  2.000
Memory limit (MB)   256

Notes

The return value is always defined. In other words, for any a, b, and c there is at least one way to build a valid triangle.

Constraints

a will be between 1 and 100, inclusive.
b will be between 1 and 100, inclusive.
c will be between 1 and 100, inclusive.

思路:Challenge的时候看到有人用遍历来实现,但是其实问题十分简单,稍微用点数学知识,很快就解决了。
代码:

class TriangleMaking:
    def maxPerimeter(self, a, b, c):
        L=[a,b,c];
        L.sort()
        if L[0]+L[1]<=L[2]:
            return 2*(L[0]+L[1])-1
        else:
            return sum(L)

500分题目
Problem Statement

You are given a int[] b containing a sequence of n positive integers: b[0], …, b[n-1]. We are now looking for another sequence a[0], …, a[n-1]. This sequence should have the following properties:

  1. Each a[i] should be a number of the form 2^x[i] where x[i] is some positive integer. In other words, each a[i] is one of the numbers 2, 4, 8, 16, …
  2. For each i, the value a[i]^b[i] (that is, a[i] to the power b[i]) should be divisible by P, where P is the product of all a[i].

Determine whether there is at least one sequence with the desired properties. Return “Possible” (quotes for clarity) if such a sequence exists and “Impossible” otherwise.
Definition

Class   DivisibleSetDiv2
Method  isPossible
Parameters  tuple(integer)
Returns string
Method signature    def isPossible(self, b)
(be sure your method is public)

Limits

Time limit (s)  2.000
Memory limit (MB)   256

Constraints

b will contain between 1 and 50 elements, inclusive.
Each element in b will be between 1 and 10, inclusive.

思路:这道题目,初看是道关于整除的问题。我看到确实有人通过遍历所有情况,然后判断是否整除来实现,最后也能通过测试。但是仔细思考就会发现这就是一道关于判断矩阵是否正定的题目。每个 a[i] 对应一个 x[i],最终 a[i]^b[i] 能否被 product(a[i]) 整除,就是判断 x[i]*b[i] 是否大于 sum(x[i]), 将每个b[i]对应的不等式列出来,求解x[i],于是最终的问题就相当于求矩阵A
1-b[1] 1 … 1
1 1-b[2] … 1

1 1 ….. 1-b[n]
与x的趁机 A*X>0的解。可以看出A必然为满秩矩阵,那么只要A为正定矩阵,最终得到的结果就是Xi>0,否则,就会出现Xj<0的情况。A是实对称矩阵,判断它是否为正定矩阵,只需要判断其顺序主子式是否全部大于0即可。

于是,最终代码为:

class DivisibleSetDiv2:
    def isPossible(self, b):
        ret=1.0
        Pi=1.0
        for s in b:
            ret-=1.0/s
            Pi=Pi*s
            P=Pi*ret
            if P<-1.0/100:
                return "Impossible"
        return "Possible"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值