D17-Acwing-继续复习826-841

33 篇文章 0 订阅
23 篇文章 0 订阅

刚刚写完了背包的实现。
现在抓紧复习一下之前的一些代码,还有20多分钟。

828模拟栈

比较顺利,除了输出的大小写字母错了

N = 100010
m = int(input())

stk,tt = [0]*N,0

def push(x):
    global tt
    tt+=1
    stk[tt] = x
def pop():
    global tt
    tt-=1
def empty():
    global tt
    if tt>0:
        return False
    else:
        return True
def query():
    global tt
    return stk[tt]
    
for _ in range(m):
    op,*pt = input().split()
    if op=='push':
        x = int(pt[0])
        push(x)
    elif op == 'pop':
        pop()
    elif op == 'empty':
        if empty():
            print('YES')
        else:
            print('NO')
    else:
        print(query())


829模拟队列

除了空和不空逻辑有点逆反,没什么问题

m = int(input())
N = 100010

q = [0]*N
hh,tt = 0,-1
def push(x):
    global tt
    tt += 1
    q[tt] =x
def pop():
    global hh
    hh+=1 
def empty():
    global hh,tt
    if hh<=tt:
        return False
    else:
        return True
def query():
    return q[hh]

for _ in range(m):
    op, *pt = input().split()
    if op=='push':
        x = int(pt[0])
        push(x)
    elif op =='pop':
        pop()
    elif op == 'empty':
        if empty():
            print('YES')
        else:
            print('NO')
    else:
        print(query())

830单调栈

不知道哪里错了,先去吃饭,回去下午再看吧

n = int(input())
nums = list(map(int,input().split()))
N = 100010


stk, tt = [0]*N, 0

for i in range(n):
    x = nums[i]
    while not tt and x<=stk[tt]:
        tt -=1
    if not tt:
        print('-1', end=' ')

    else:
        print(stk[tt],end=' ')
    tt+=1
    stk[tt] = x
        
        

不错!!!下午睡醒了,1分钟就调出来了
while not tt,是tt为空,但实际上想说的是tt不为空,是while tt。

n = int(input())
nums = list(map(int,input().split()))
N = 100010


stk, tt = [0]*N, 0

for i in range(n):
    x = nums[i]
    while tt and x<=stk[tt]:
        tt -=1
    if not tt:
        print('-1', end=' ')

    else:
        print(stk[tt],end=' ')
    tt+=1
    stk[tt] = x
        
        

先去看y总新课啦~
现在是2022年3月29日14:57,我已经看完了y总的dp二,没想到效率可以这么高!!!很开心,很满足,下午这段时间作为完成highlight的时间真的很不错!!!
现在先休息一下,打个水、上个厕所,也许看个视频,想看锦堂了,然后回来继续复习题~~~

154滑动队列

这道题的问题还是比较大的。
1、思路:
q队列里维持的是数组中、窗口内最小值的下标
所以需要不断判断下标是否在窗口内。如果新加入的元素比原来的小或者等于,则加入队列;否则,则不用。
2、q的初始化为【0】*N,不过在使用时需要判断队列中是否有值——if hh<=tt
3、真正数组中的值是a[q[hh]],q[hh]只是下标

N = 1000010

n,k = map(int, input().split())
nums = list(map(int,input().split()))
q = [0]*N
tt,hh = -1,0

for i in range(n):
    x = nums[i]
    # 先判断队列是否有值
    if hh<=tt and q[hh]<i-k+1:
        hh += 1
    # q[tt]中是下标,需要用nums数组
    while hh<=tt and nums[q[tt]]>=x:
        tt-=1
    tt+=1
    # q[tt]是下标
    q[tt] = i
    if i >= k-1:
        print(nums[q[hh]], end=' ')
print()
q = [0]*N
tt,hh = -1,0

for i in range(n):
    x = nums[i]
    # 先判断队列是否有值
    if hh<=tt and q[hh]<i-k+1:
        hh += 1
    # q[tt]中是下标,需要用nums数组
    while hh<=tt and nums[q[tt]]<=x:
        tt-=1
    tt+=1
    # q[tt]是下标
    q[tt] = i
    if i >= k-1:
        print(nums[q[hh]], end=' ')

831KMP

令人跃跃欲试的kmp, Come on buddy!
尽管不是那么丝滑,但是比之前好很多了啊!!
1、j = 0开始
2、p自循环的时候,ne[i]=j是不在if条件内的,也就是说j==0的情况,也是要记录在ne【i】中的,相当于这个时候没有匹配上。

n = int(input())
p = ' ' + input()
m = int(input())
s = ' ' + input()

N = 100010
ne = [0]*N

j = 0 
for i in range(2,n+1):
    while j and p[i]!=p[j+1]:
        j = ne[j]
    if p[i]==p[j+1]:
        j += 1
    ne[i] = j

j = 0
for i in range(1,m+1):
    while j and s[i]!=p[j+1]:
        j = ne[j]
    if s[i]==p[j+1]:
        j += 1
        if j == n:
            print(i-j, end=' ')
            j = ne[j]
            

835

整体思路上没有任何问题,主要问题出在
1、未设置p指针,导致idx和p混乱
2、用pt接收时,不用打*pt,因为本身就是两个字符串
3、设置函数来分别执行两个操作更清晰一点(其实我也不确定,只是刚开始没有分为函数,并且有以上两个错误,就分为函数了,具体不知道部分为函数会不会好一些,但是分为函数还是比较清晰的)
代码如下:

# Trie树一般用来储存和查找字符串
N = 100010

n = int(input())
son = [[0]*26 for _ in range(N)]
idx,cnt = 0,[0]*N

def insert(string):
    global idx
    p = 0
    for i in range(len(string)):
        u = ord(string[i]) - ord('a')
        if not son[p][u]:
            idx += 1
            son[p][u] = idx
        p = son[p][u]
    cnt[p] += 1
def query(string):
    global idx
    p = 0
    for i in range(len(string)):
        u = ord(string[i]) - ord('a')
        if not son[p][u]:
            return 0
        p = son[p][u] 
    return cnt[p]
for _ in range(n):
    op, pt = input().split()
    string = str(pt)
    if op=='I':
        insert(string)
    else:
        print(query(string))
        

    

锻炼完了,继续来写题!!!还有精神,真好!!!!

836

比较顺利
但是注意p=[x for x in range(N)]

# 并查集用来维护集合;并且查询两个元素是否在集合中
N = 100010

n,m = map(int,input().split())
p = [x for x in range(N)]

def find(x):
    if p[x]!=x:
        p[x] = find(p[x])
    return p[x]
def merge(a,b):
    if find(a)!=find(b):
        p[find(a)] = find(b)
def query(a,b):
    if find(a)==find(b):
        return True
    else:
        return False

for _ in range(m):
    op,*pt = input().split()
    a,b = map(int,pt)
    if op == 'M':
        merge(a,b)
    else:
        if query(a,b):
            print('Yes')
        else:
            print('No')
    

837

好奇怪,我觉得代码没任何不一样啊,为啥结果不一样

n,m = map(int,input().split())
N = 100010
p = [x for x in range(N)]
cnt = [1]*N
def find(x):
    if x!=p[x]:
        p[x] = find(p[x])
    return p[x]
    
for _ in range(m):
    op,*pt = input().split()
    if op == 'C':
        a,b = map(int,pt)
        if find(a)!=find(b):
            cnt[find(b)] += cnt[find(a)]
            p[find(a)] = find(b)
    elif op == 'Q1':
        a,b = map(int,pt)
        if find(a)==find(b):
            print('Yes')
        else:
            print('No')
    else:
        a = int(p[0])
        print(cnt[find(a)])
    

啊啊啊啊是倒数第二行,应该是pt的,写成p了。奇怪的是居然也有p数组,不会报错。

838

输出后别忘记down(1),问题不大。
另外,只有t!=u,两值交换后,才需要down(t)。

n,m = map(int,input().split())

N = 100010
h = [0] + [int(x) for x in input().split()]

def down(u):
    t = u
    if 2*u<=n and h[2*u]<h[t]:
        t = 2*u
    if 2*u+1<=n and h[2*u+1]<h[t]:
        t = 2*u+1
    if t!=u:
        h[t],h[u] = h[u],h[t]
        down(t)

for i in range(int(n/2),0,-1):
    down(i)
for _ in range(m):
    print(h[1], end = ' ')
    h[1],h[n]=h[n],h[1]
    n-=1
    down(1)

839模拟堆

除了忘记在add的时候添加hp和ph的信息;
以及在写swap的时候有些不确定----ph【hp【a】】,a和b是在堆中的位置

都挺好的

n = int(input())

N = 100010
h,hp,ph,idx,size = [0]*N,[0]*N,[0]*N,0,0

def swap(a,b):
    ph[hp[a]],ph[hp[b]] = b,a
    hp[a],hp[b] = hp[b],hp[a]
    h[a],h[b] = h[b],h[a]
    
def add(x):
    global idx,size
    idx+=1
    size+=1
    h[size] = x
    hp[size] = idx
    ph[idx] = size
    up(size)
    
def down(u):
    t = u
    if 2*u <= size and h[2*u]<h[t]:
        t = 2*u
    if 2*u+1 <= size and h[2*u+1]<h[t]:
        t = 2*u+1
    if t!=u:
        swap(t,u)
        down(t)
def up(u):
    while u//2 and h[u//2]>h[u]:
        swap(u//2,u)
        u//=2
        
for _ in range(n):
    op, *pt = input().split()
    if op=='I':
        x = int(pt[0])
        add(x)
    elif op=='PM':
        print(h[1])
    elif op=='DM':
        swap(1,size)
        size-=1
        down(1)
    elif op=='D':
        k = int(pt[0])
        k = ph[k]
        swap(k,size)
        size-=1
        down(k)
        up(k)
    else:
        k,x = map(int,pt)
        k = ph[k]
        h[k] = x
        up(k)
        down(k)
        
        
    

840模拟散列表

就是x的数值太大了,而N的次数太少了,x整体分布比较系数,这种哈希表可以把x稠密化。
具体操作的时候注意N是最大个数2-3倍以上的第一个质数,是一个经验值

N,null = 200003,0x3f3f3f3f

s = [null]*N

def find(x):
    k = x%N
    while s[k]!=null and s[k]!=x:
        k+=1
        if k==N:
            k=0
    return k

n = int(input())
for _ in range(n):
    op, pt = input().split()
    x = int(pt)
    if op=='I':
        s[find(x)] = x
    else:
        if s[find(x)]==x:
            print('Yes')
        else:
            print('No')
    
    

841字符串哈希

这题不是很熟悉了
1、s[i]的计算应该是(s[i-1]*P+ord(string[i]))%Q
2、getHash函数的定义
return 的是s[r]-s[l-1]*p[r-l+1] 再%Q,基本上忘了鹅鹅鹅

n,m = map(int,input().split())
string = ' ' + str(input())
N = 100010
P,Q = 131,2**64
p,s = [0]*N,[0]*N
p[0]=1
for i in range(1,1+n):
    p[i] = p[i-1]*P%Q
    s[i] = (s[i-1]*P+ord(string[i]))%Q
    
def getHash(l,r):
    return (s[r]-s[l-1]*p[r-l+1])%Q

for _ in range(m):
    l1,r1,l2,r2 = map(int,input().split())
    if getHash(l1,r1)==getHash(l2,r2):
        print('Yes')
    else:
        print('No')

累啦累啦,我要写个日记、剪会视频就睡啦~~晚安~今天很愉快!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值