12
返回列表 发新帖
楼主: 〇〇

牛学奥林匹克

[复制链接]
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
11#
 楼主| 发表于 2021-12-18 18:36 来自手机 | 只看该作者

s=[1,2,3,4,3,2,5]

ml=[0 for i in range(len(s))]
mr=[len(s)-1 for i in range(len(s))]
#ml,mr分别保存每个位置的最长左右子串的终点位置
def pre(s):
x=len(s)
for i in range(x):
   for j in range(i+1,x):
     if s[j]==s[i]:
       mr[i]=j-1
       break
   for j in range(i-1,0,-1):
     if s[j]==s[i]:
       ml[i]=j+1
       break

pre(s)
>>> ml
[0, 0, 0, 0, 3, 2, 0]
>>> mr
[6, 4, 3, 6, 6, 6, 6]
>>> s
[1, 2, 3, 4, 3, 2, 5]      
  
def j3(b,e):
     x=[]
     l,r=s[b],s[e]
     if l!=r and mr[b] >=e and ml[e] <=b:
       if e-b==2:
        x.append(1)
       else:
        for i in range(1,e-b):
         if mr[b+i] >=e and ml[b+i] <=b:
           x.append(i)
     return len(x),x

def lp3(s):
     cnt=0
     for b in range(0,len(s)-2):
      for e in range(b+2,len(s)):
        s1=s[b:e+1]
        #print("test ",s1)
        c,x=j3(b,e)
        if c>0:
          #print(s1)
          #for y in x:
            #print("lead",(b+1,b+y+1,e+1))
          cnt+=c
     print("cnt=",cnt)

>>> lp3(s)
cnt= 19600
>>> s=list(range(200))
>>> ml=[0 for i in range(len(s))]
>>> mr=[len(s)-1 for i in range(len(s))]
>>> pre(s)
>>> t=time.time();lp(s);print(time.time()-t)
cnt= 1313400
11.5908203125
>>> t=time.time();lp3(s);print(time.time()-t)
cnt= 1313400
1.029601812362671
#比原始快了10倍
>>> s=list(range(300))
>>> ml=[0 for i in range(len(s))]
>>> mr=[len(s)-1 for i in range(len(s))]
>>> pre(s)
>>> t=time.time();lp3(s);print(time.time()-t)
cnt= 4455100
3.2916059494018555

#不保存领队,只计数
def j4(b,e):
     x=[]
     l,r=s[b],s[e]
     c=0
     if l!=r and mr[b] >=e and ml[e] <=b:
       if e-b==2:
        c=1
       else:
        for i in range(1,e-b):
         if mr[b+i] >=e and ml[b+i] <=b:
           c+=1
     return c

def lp4(s):
     cnt=0
     for b in range(0,len(s)-2):
      for e in range(b+2,len(s)):
        c=j4(b,e)
        if c>0:
          cnt+=c
     print("cnt=",cnt)

>>> t=time.time();lp4(s);print(time.time()-t)
cnt= 4455100
3.057605504989624
#没有提高

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
12#
 楼主| 发表于 2021-12-19 08:22 来自手机 | 只看该作者
我的是O(NNN)的,标准答案
http://usaco.org/current/data/sol_prob1_platinum_open21.html
有个很强大很短的O(NN),没看懂,改写如下

def nn(B):
        ans = 0
        N=len(B)
        for r in range(0,N) :
                occ =[0 for i in range(N+1)]
                unique = 0
                for l in range(r-1, -1,-1) :
                        if (B[l] == B[r]): break
                        occ[B[l]]+=1
                        if (occ[B[l]]== 1) :
                                ans += unique
                                unique+=1
                        elif (occ[B[l]] == 2) :
                                unique-=1
        print(ans)
       


t=time.time();nn(s);print(time.time()-t)
cnt= 4455100
1.54115891456604
4455100
0.023647546768188477

[Program finished]

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
13#
 楼主| 发表于 2021-12-19 20:44 来自手机 | 只看该作者
O(NN)对20万还是太慢,所以答案里有O(NlogN)的程序

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
14#
 楼主| 发表于 2021-12-19 20:48 来自手机 | 只看该作者
前面是白金级的题,还有黄金级,2个领队。
http://usaco.org/index.php?page=viewproblem2&cpid=1137&lang=zh

使用道具 举报

回复
论坛徽章:
0
15#
发表于 2021-12-20 00:45 来自手机 | 只看该作者
Take 12234556 as input.  For m in 1..8, for n in m+1..8, do something, end.  Now if n=1, start=1, end={4,6}, and mid={...} for each end.  For n=2 start=2 exit from loop m because 2nd 2 found before length=3.  For n=3, start=2 end={4,6} ... for n=4, start=3 end={6} ... for n=5,6 no valid. For n>6 no enough member (so should be m in 1..6 loop).  I can understand without exit in the nested loop it is about N*N in total loop processing.  But what is N*logN?

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
16#
 楼主| 发表于 2021-12-25 22:26 来自手机 | 只看该作者
http://usaco.org/index.php?page=dec21results 12月

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表