有意思的各类算法,思维题目分享

news2024/7/6 20:41:12

1.统计子矩阵

 思路:二维前缀和超时,下面是前缀和加双指针,对列前缀和,两个玄幻控制行号,双指针控制列的移动

考查:前缀和+双指针

import os
import sys

# 请在此输入您的代码
# 矩阵大小  N × M
n,m,k=map(int,input().split())  #默认用空格隔开
s=[[0 for i in range(m+1)]]   #定义一个数组
for i in range(1,n+1):
  s.append([0]+list(map(int,input().split())))
  for j in range(1,m+1):   
    s[i][j]+=s[i-1][j]   # 列的前缀和
res=0
for i in range(1,n+1):
  for j in range(i,n+1):   #枚举上下边界
    l=1          #双指针,对列用的双指针
    sum=0
    for r in range(1,m+1):    #这部分计算的是区域和
      sum+=s[j][r]-s[i-1][r]   #r列的值+
      while sum>k:
        sum-=s[j][l]-s[i-1][l]
        l+=1
      res+=r-l+1
print(res)

附上二维前缀和代码

import os
import sys

# 请在此输入您的代码

n,m,k = map(int,input().split())
a=[[0] for i in range(n)]
a.insert(0,[0]*(m+1))
for i in range(1,n+1):  # 转换二维矩阵形式,即下标从1开始
  a[i].extend(map(int,input().split()))

s = [[0]*(m+1) for i in range(n+1)]  # 预计算前缀和s[][]
for i in range(1,n+1):
  for j in range(1,m+1):
    s[i][j] = s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j]

ans =0
for i1 in range(1,n+1):
  for i2 in range(i1,n+1):
    for j1 in range(1,m+1):
      for j2 in range(j1,m+1):
        cal  = s[i2][j2]-s[i2][j1-1]-s[i1-1][j2]+s[i1-1][j1-1]
        if cal<= k: ans+=1

print(ans)

2.子串分值

 把问题转换为单个字符能够创造的的价值求和,就是他当前x下标与前后x下标内下标的组合

考查:思维

s = ' ' + input()
n = len(s) - 1

index = {}

# 计算每一个元素能创造的价值
# 累计每一个元素的价值

for i in range(1, n + 1):
    c = s[i]

    if c not in index:
        index[c] = [0]
    
    index[c].append(i) #记录出现的位置


cnt = 0
for value in index.values():
    value.append(n + 1)
    # size = len(value)-2
    for i in range(1, len(value) - 1):
        cnt += (value[i] - value[i - 1]) * (value[i + 1] - value[i])    # 有多少取的种方法,就是它能创造的组合

print(cnt)

3.蓝桥杯国赛题目机器人塔

DFS搜索或者循环来做,可以学习Python缓存lru_cache的用法,即内置记忆化存储,用了这个可以加快运算效率,避免重复运算。

这道题结合二进制,同时从下到上递推,然后用了位运算等知识。

'''
# python3.6
# -*- coding: utf-8 -*-
# @Time    : 2023/5/12 13:01
# @Author  : Jin
# @File    : test2.py
# @Software: PyCharm
import os
import sys
import math

# 请在此输入您的代码
#机器人塔
from functools import lru_cache
a,b=(int(i) for i in input().split())
n=int(math.sqrt((a+b)*2))

@lru_cache(None)
def f(n,x,a,b):
    if n==1:  # 出去边界
        if x==0:
            return a-1==0
        else:
            return b-1==0
    if a<0 or b<0 :  # 直接剪枝
        return
    #print(bin(x))
    cnt=bin(x)[2:].count('1')
    a=a-(n-cnt)
    b=b-cnt
    next=(x^(x>>1))&((2**(n-1)-1))
    #print(bin(next))
    return f(n-1,next,a,b)
c=0
for m in range(0,1<<n):
    if f(n,m,a,b):  # 层数,状态,机器人数量a 0,机器人数量b 1
        c+=1
print(c)

'''
import os
import sys

# A-AA/BB; B-AB/BA,A-0; B-1;符合异或运算
m, n = map(int, input().split())

def check(now, num):
    num_a, num_b = 0, 0
    for i in range(num, 1, -1):  # i是层数也是机器人个数
        ls = list(bin(now))[2:]
        num_b += ls.count('1')
        num_a += i - ls.count('1')
        # 求上一层的状态
        # now右移一位相当于把now最低位的状态移走,再和原本的now异就得到上层结果,但是最高位要通过与运算去掉,
        # 这相当于原本的now除了最高位其他每一位都和前一位进行了异或,结果为1说明可以站B,为0站A
        now ^= (now >> 1)
        now &= (2**(i - 1) - 1)  # 移除now最高位的状态
    if now == 1: num_b += 1
    else: num_a += 1
    return num_a == m and num_b == n

# num*(num+1)//2 = m+n
num = int(((m + n) * 2) ** 0.5)  # 层数0~num-1 ,最后一层的个数
ans = 0
for i in range(1 << num):  # 最下面一层有num个数,有00..~11..种状态
    if check(i, num): ans += 1
print(ans)

4.跳蚂蚱

BFS模板题,主要是这个可以使用双向广搜,BFS双向广搜,了解一下写法。注意有时候BFS需要结合copy库来使用

import collections
import sys
meet=False   #判断是否相遇

def extend(q,m1,m2):
  global meet
  s=q.popleft()
  ss=list(s)
  index=ss.index('0') #找0的索引
  for j in [1,-1,2,-2]:
    ss[(index+j+9)%9],ss[index]= ss[index],ss[(index+j+9)%9]
    a=''.join(ss)
    if a in m2:  # 找到相同的了,即相遇了
      print(m1[s]+1+m2[a])
      meet=True
      return
    if a not in m1:
      q.append(a)
      m1[a]=m1[s]+1  # 向字典中添加
    ss[(index+j+9)%9],ss[index]= ss[index],ss[(index+j+9)%9]
 # meet=False

q1=collections.deque()
q2=collections.deque()
q1.append("012345678")
q2.append("087654321")
# 字典去重,同时记录步数
mp1={'012345678':0} ; mp2={'087654321':0}
while q1 and q2 :  # 两个都不为空
  if len(q1)<=len(q2): extend(q1,mp1,mp2)
  else:  extend(q2,mp2,mp1)
  if meet==True: break

5.树状数组处理逆序对

逆序对,两种方法,前面比他大的(正序树状数组),后面比他小的(倒叙树状数组),

import os
import sys

# 每个人的交换次数等前面严格大于自身的人数+后面严格小于自身的人数 数据范围是10^5暴力枚举O(n^2)会超时,此时就想到要用的树状数组或归并排序
#只有60%
# 请在此输入您的代码
N=1000010
def discretization(h):#数组离散化
    temp=list(set(h))
    temp.sort()
    for i in range(len(h)):
        h[i]=temp.index(h[i])+1
def lowbit(x):
    return x&-x
def update(x,d):
    while x<=N:
        tree[x]+=d
        x+=lowbit(x)
def sum(x):
    ans=0
    while x>0:
        ans+=tree[x]
        x-=lowbit(x)
    return ans

n=int(input())
hold=list(map(int,input().split()))  #身高
h=[0 for i in range(N)]  
for i in range(n):  # 转为下标从1开始
    h[i+1]=hold[i]
discretization(h) #数组离散化,但是因为本题的数字没超出范围就不需要了
k=[0 for i in range(N)]#每个小朋友要交换的次数
tree=[0 for i in range(N)] # 树状数组
for i in range(1,n+1): #正序处理,他后面的逆序对数量
    update(h[i],1)
    k[i]=i-sum(h[i])  # 计算h[i]前面的逆序数,前面有i-sum(h[i])个比他大的
   
tree=[0 for i in range(N)]
for i in range(n,0,-1): #倒序处理,他前面的逆序对数量
    k[i]+=sum(h[i]-1)  #计算h[i],后面有sum(h[i]-1)个比他小的
    update(h[i],1)
res=0  
for i in range(1,n+1):
    res+=int((1+k[i])*k[i]/2)  #等差数列
print(res)

归并排序处理逆序对

def merge_sort(L,R):
    if L < R:
        mid = (L+R)//2
        merge_sort(L,mid)
        merge_sort(mid+1,R)
        merge(L,mid,R)
def merge(L,mid,R):
    global res   # 记录答案
    i=L;j=mid+1;t=0
    while(i<=mid and j<=R):  #归并
        a[i]
        a[j]
        if (a[i]>a[j]):     #4 5 / 2 3   L=0 mid=1,R=3
            b[t]=a[j];t+=1;j+=1;
            res = res+(mid-i+1)  # 记录逆序对数量
        else:
            b[t] = a[i];t += 1;i += 1
    # 其中一个处理完了,把剩下的复制过来,直接整体复制
    # 这里注意区间取值,采用的是整体复制的思想,b是辅助数组
    if i<=mid: b[t:R-L+1]=a[i:mid+1]  # 取不到mid+1
    elif j<=R:b[t:R-L+1]=a[j:]
    # 把排序好的b[]复制回去a[]
    a[L:R+1]=b[:R-L+1]
n= int(input())
a = list(map(int,input().split()))
b = [0]*n
res = 0
merge_sort(0,n-1)
print(res)

6.数组切分

 DP的做法,python效率低所以不能AC

 

# 超时了两个,80%,思路没问题 
mod = 1000000007
N = 10010


f = [0 for i in range(N)]
n = int(input())
a =[0]+ list(map(int,input().split()))

f[0]=1
for i in range(1,n+1):
    mx=a[i]
    mi=a[i]
    for j in range(i,0,-1):
        mx = max(mx,a[j])
        mi = min(mi,a[j])
        if mx-mi == i-j:
            f[i] = (f[i]+f[j-1]) % mod   #dp思想  一个指针依次遍历i,另一个从当前位置回滚回去,长度从1变大,利用前一步结果计算
print(f[n])

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/540175.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

某大学信息安全竞赛——shellcode1 绕过strlen检查,绕过沙箱检查,执行orw shellcode拿到flag

题目自取&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1HrMqh-lX-mkfueVeLzoEJg 提取码&#xff1a;oyel 介绍下这可恶的沙箱机制 这是一道非常让人蛋疼的题目&#xff0c;之前我只听说过沙箱&#xff0c;但是并没有自己实际接触过沙箱这个保护机制&#xff0c;大…

PX4从放弃到精通(二十八):垂起过渡控制

文章目录 前言一、主程序二、update_transition_state&#xff08;&#xff09;三、update_transition_state&#xff08;&#xff09; 前言 固件版本&#xff1a;1.14.0 可加名片交流学习 一、主程序 代码位置&#xff1a; 构造函数&#xff0c;用初始化列表进行初始化工作…

图可视分析

G6简介 AntVG6是一个基于WebGL的图形可视化引擎&#xff0c;它提供了一种简单、高效、灵活的方式来创建各种类型的图形&#xff0c;包括流程图、关系图、树形图、桑基图、饼图等等。它的主要思想是将图形分解为节点和边&#xff0c;并使用数据来描述它们之间的关系。 它的特性包…

BMPFont使用教程--免费的位图字体制作工具字体制作(2)

1、下载windows免费的位图字体制作工具Bitmap Font Generator 下载地址&#xff1a;BMFont - AngelCode.com 2、打开软件-> Edit -> Open Image Manager 3、点击Image -> Import Image,选择字符对应的图片&#xff0c;id就填写下面的48&#xff0c;代表0&#xff0c;…

Redis 主从复制 哨兵 集群

哨兵&#xff1a;在主从复制的基础上&#xff0c;哨兵实现了自动化的故障恢复。缺陷&#xff1a;写操作无法负载均衡&#xff1b;存储能力收到单机的限制&#xff1b; Cluster集群&#xff1a;通过集群&#xff0c;Redis解决了写操作无法负载均衡&#xff0c;以及存储能力收到…

应用现代化中的弹性伸缩

作者&#xff1a;马伟&#xff0c;青云科技容器顾问&#xff0c;云原生爱好者&#xff0c;目前专注于云原生技术&#xff0c;云原生领域技术栈涉及 Kubernetes、KubeSphere、KubeKey 等。 2019 年&#xff0c;我在给很多企业部署虚拟化&#xff0c;介绍虚拟网络和虚拟存储。 2…

智能图像处理技术:开启未来视觉时代

写在前面技术论坛■ 智能文档图像处理技术■ 大模型时代的文档识别与理解■ 篡改文本图像的生成与检测 圆桌讨论未来愿景 写在前面 文档 是人们在日常生活、工作中产生的信息的重要载体&#xff0c;各领域从业者几乎每天都要与金融票据、商业规划、财务报表、会议记录、合同、…

【JAVA程序设计】(C00138)基于Servlet+jsp的药店管理系统

基于Servletjsp的药店管理系统 项目简介项目获取开发环境项目技术运行截图 项目简介 本项目是简单的药店管理系统&#xff0c;本系统使用servlet和jsp的技术&#xff0c;本系统有一种权限管理员&#xff1a; 其功能有&#xff1a;管理员管理&#xff08;增删改查&#xff09;、…

TypeScript为什么要有对象?怎样创建对象

什么是TypeScript的对象&#xff1f; 生活中&#xff0c;对象是一个具体的事物&#xff0c;比如&#xff1a;你的电脑、你的手机、古力娜扎、周杰伦(周董)等都是对象。 但在程序员的认知中万物皆对象。 这些具体的事物&#xff0c;都有自己的特征和行为&#xff1a; 特征&…

云his门诊业务模块常见问题分析和门诊业务使用流程

一、门诊医生如何查询往期病人 鼠标点击门诊医生站左侧患者列表&#xff0c;在弹出的页面点击已诊分页&#xff0c;在搜索框输入患者姓名&#xff0c;在结果中找到对应患者&#xff0c;点击详情按钮即可查询患者往期就诊信息&#xff0c;点击想要查询的门诊记录前方的方框即可…

[数据结构 -- C语言] 队列(Queue)

目录 1、队列 1.1 队列的概念及结构 2、队列的实现 2.1 接口 3、接口的实现 3.1 初始化队列 3.2 队尾入队列 分析&#xff1a; 3.3 队头出队列 分析&#xff1a; 3.4 获取队列头部元素 3.5 获取队列尾部元素 3.6 获取队列中有效元素个数 3.7 检测队列是否为空 3…

要想抢到演出票,总共分几步?

点击文末“阅读原文”即可参与节目互动 剪辑、音频 / 小黑 编辑 / SandLiu 卷圈 监制 / 姝琦 文案 / 小黑 产品统筹 / bobo 录音支持 / 声湃轩天津录音间 报复性听歌正席卷多地&#xff0c;一路狂飙的演唱会市场背后&#xff0c;是一票难求、与黄牛斗智斗勇的粉丝们。 是…

GPT专业应用:自动撰写宣传稿

●图片由Lexica 生成&#xff0c;输入&#xff1a;Staff working on product promotion 宣传稿是指按照有关政策文件或相关精神&#xff0c;以宣传某种主张、某项工作、某件事情等为目的&#xff0c;为获得理解、支持而撰写的应用文。基本格式包含四个要素&#xff0c;分别是标…

chatgpt赋能Python-numpy如何下载

如何下载Numpy 对于python编程者&#xff0c;numpy是不可或缺的一个库。它提供了一种操作向量、矩阵、数组的方式&#xff0c;使得我们能够高效地进行数据处理和科学计算&#xff0c;甚至还能进行线性代数运算和傅里叶变换等高级操作。 那么&#xff0c;在这篇文章中&#xf…

第十七章 使用PXE+Kickstart无人值守安装服务

文章目录 第十七章 使用PXEKickstart无人值守安装服务一、无人值守系统1、无人值守安装系统的工作流程2、PXE介绍 二、部署相关服务程序1、临时关闭防火墙2、配置DHCP服务程序&#xff08;1&#xff09;、安装dhcp服务程序&#xff08;2&#xff09;、编辑配置文件&#xff08;…

为什么需要代理ip

使用代理IP的情况不限于某一特定行业&#xff0c;因为在不同行业中都可能需要根据不同需求和目的来使用代理IP。以下是一些行业中常见需要使用代理IP的情形&#xff1a; 1、爬虫行业 对于需要爬取网站数据的用户&#xff0c;使用代理IP可以帮助隐藏真实IP地址及请求头信息&am…

Flowable 生成的表都是干嘛的?(二)

一.简介 Flowable 默认一共生成了 79 张数据表&#xff0c;了解这些数据表&#xff0c;有助于我们更好的理解 Flowable 中的各种 API。 接下来我们就对这 79 张表进行一个简单的分类整理。 ACT_APP_*&#xff08;5&#xff09;ACT_CMMN_*&#xff08;12&#xff09;ACT_CO_*…

Linux之后台终端

1、后台终端 当我们连接一个终端并执行一个程序时&#xff0c;关闭终端时程序也被终结。比如想在终端中执行一个web服务器&#xff0c;想一直后台运行&#xff0c;可以使用screen这个工具 2、screen工具 screen工具不是自带的所以需要sudo apt update && sudo apt i…

excel 甘特图制作(详细)

文章目录 前言excel 甘特图制作(详细)1. 模板字段确认2. 冻结至F列3. 在第二行确认状态颜色4. 设置开始日期5. 先将第3行居中&#xff0c;然后状态那列设置下拉6. 填充任务7. 开启日期与结束日期设置单元格式为日期8. 填充任务9. 制作日期10. 制作日期交互11. 修改开始时间范围…

数说故事与华为云签署全面合作协议,共同升级数字世界营销新体验

5月16日&#xff0c;由广东省工业和信息化厅、广州市人民政府联合指导&#xff0c;华为主办的2023华为云城市峰会首站登录广州。为贯彻落实广东省高质量发展大会的工作要求&#xff0c;响应《广东省制造业高质量发展“十四五”规划》, 本次大会围绕“在工业 为工业”主题并邀请…