谷歌中国算法比赛解题报告 APAC2017B

Problem A. Sherlock and Parentheses

Problem B. Sherlock and Watson Gym Secrets

Problem C. Watson and Intervals

Problem D. Sherlock and Permutation Sorting


好吧,lz还是没时间好好做完做这四道题……2017年的题,如果我能考过最后一场,我会回来补上。


随便说说吧。

第一题,其实就是求n*(n+1)/2。 肯定()()()这种是最优的


2. 这题有些难度,首先 i的a次方等于 a为偶数的话就是 i**(a/2) 的平方,a为奇数的话就是 i**((a-1)/2) 的平方乘i,这样可以迅速求出i的a次方的模,第二步观察K<100000,所以N虽然大,其实我们只要计算到K就行,后面都是重复


3. 这题没空做


4. 这题,标准解法非常数学……我没看懂,但是这题可以用dp暴力解(好可怕,dp都算暴力解了),只要找到了规律。

让我们来看看规律

首先准备一个二维数组,C[i][j]  这里第一维是数组长度,第二维是每个最大子数组的数量

 比如 C[2][1]=1 代表长度2的数组有1个只能分一个子数组的数组

对应题目 C[1][1]=1 C[2][1]=1 C[2][2]=1 C[3][3]=1 C[3][2]=2 C[3][1]=3

如果接着往后画,会得出

1

1   1

3   2   1

13 7   3   1

然后找到规律 比如第三层, 

第四层的1是传自第三层的1

第四层的3 是加了第三层的2 和第三层的1 

第四层的7 是加了第三层的 2的((2*4)-2)/2 和第三层的1 和第三层的3 

第四层的13 是加了第三层的1 和2 的(((2*4)-2)/2 )和3的((3*4)-3)/1

也就是C[i][j]= 求和对每个j(C[i-1][j]*i-C[i-1][j])/(j)

找到规律了开心吧,如果就这么去用c++做,对不起,错了!

为什么错了,我们找的规律肯定没错

错在取模上,注意 8%5=3  8除2 再%5 等于3么?

因为这题要取模,所以不能用除法!!!!!!!!

好吧,如果要正宗做请去搜英文的解题方法,我看到有老外POST了

否则的话,请用python!

完美解决,数位再多,又有何妨?

不过有点慢,对于大数据,我们可以先初始化一遍,虽然有点慢,但8分钟内还是够的

这次只上最后一题的python代码了,我先把问题存了起来,然后扫一遍碰到问题就求解

MAXLINE=5001

def checkFlag(key,currline):
    if flags[key]==True:
        for i in range(len(questions)):
            if questions[i][0]==key:
                total=0;
                for j in range(1,key+1):
                    t1=currline[j]%questions[i][1];
                    total+=t1*j*j;
                answer[i]=total%questions[i][1];
        flags[key]=False;



def singleProcess():
    line1=[0 for i in range(MAXLINE)];
    line2=[0 for i in range(MAXLINE)];
    cells=[0 for i in range(MAXLINE)];
    currLine=line1;
    nextLine=line2;


    currLine[1]=1;
    checkFlag(1,currLine)

    for i in range(2,MAXLINE):
        total=0;
        print(i);
        for j in range(1,i):
            cells[j]=currLine[j]*(i-1)//j
            total+=cells[j]
        for j in range(1,i+1):
            nextLine[j]=currLine[j-1]+total;
            total-=cells[j]

        temp=currLine;
        currLine=nextLine;
        nextLine=temp;
        checkFlag(i,currLine)


if __name__ == "__main__":
    input=open("../in.txt","r")
    output=open("../out.txt","w")
    T=int(input.readline())
    questions=[];
    flags=[False for i in range(MAXLINE)]
    for case in range(T):
        strs=input.readline().split(' ')
        N=int(strs[0])
        M=int(strs[1])
        questions.append((N,M));
        flags[N]=True;

    answer = [0 for i in range(len(questions))]
    singleProcess()
    for case in range(T):
        output.write("Case #%d: %s\n" % (case + 1, answer[case]))









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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值