ZAFU_2021_1_28_2021寒假个人赛第三场题解

5个4000比特大状态置换算法的设计与分析 下面是 5 个概念性、实验性的 4000 位可逆置换设计。它们都保证是双射,但未经过密码分析,不可直接用于生产系统。风格分别覆盖:三维 SPN、Feistel、可逆元胞自动机、ARX、宽轨迹/Keccak 式结构。 这 5 个设计分别代表了 SPN、Feistel、元胞自动机、ARX、宽轨迹 Keccak 五种不同风格,覆盖了主流大状态置换的构造思路。再次强调:它们只是实验性概念,若要用于实际协议,必须经过严格安全性分析。 阅读详情

A题
原题链接:https://codeforces.com/problemset/problem/1409/A
相关tag:贪心,简单结论

算出x和y的差值。
我们必然是尽可能用最大的步子10去缩短这个差值。
最后一步可能少于10。

直接算(x+y)/10+(x+y)%10!=0即可,等价于(x+y+9)/10

#include<bits/stdc++.h>
#define ll long long
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;

int32_t main()
{
    IOS;
    int t;
    cin>>t;
    while(t--)
    {
        ll a,b;
        cin>>a>>b;
        a=abs(a-b);
        cout<<(a+9)/10<<endl;
    }
}

B题
原题链接:https://codeforces.ml/problemset/problem/1201/A
相关tag:贪心

记录下每道题选每个选项的有几个人,每道题都把选的人最多的选项当做答案去算即可。

#include<bits/stdc++.h>
#define ll long long
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;

int n,m;
int num[1007][5];//num[i][j]代表第i题选'A'+j的有几个人

int32_t main()
{
    IOS;
    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        string s;cin>>s;
        for(int j=0;j<m;j++)
            num[j][s[j]-'A']++;
    }
    int ans=0;
    for(int i=0;i<m;i++)
    {
        int x;cin>>x;
        int y=0;
        for(int j=0;j<5;j++) y=max(y,num[i][j]);
        ans+=x*y;
    }
    cout<<ans<<endl;
}

C题
原题链接:https://codeforces.com/problemset/problem/1175/A
相关tag:贪心

注意到除k必然是比-1更优的,因此能整除k的时候优先使用除k,不能的时候把余数全部减掉即可。

#include<bits/stdc++.h>
#define ll long long
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;


int32_t main()
{
    IOS;
    int t;cin>>t;
    while(t--)
    {
        ll n,k;cin>>n>>k;
        ll ans=0;
        while(n)
        {
            if(n%k)
            {
                ans+=n%k;
                n-=n%k;
            }
            else {n/=k;ans++;}
        }
        cout<<ans<<endl;
    }
}

D题
原题链接:https://codeforces.com/problemset/problem/977/D
相关tag:dfs,排序

给出dfs和结论后排序两种做法。

注意到最多只有100个数字,并且每个数字可能的变换方法只有两种。
我们可以把每个数字看成一个点,每种变换方式都是一条单向边,那么每个点最多只有两条出边,也就是整个图最多只有200条有向边(当然这种情况是不存在的)。
我们可以暴力枚举起点是哪一个进行dfs搜索,单次搜索这张无环有向图的复杂度等于有向边的数量。
总复杂度最大为O(2×\times×n×\times×n)

由于点的数量n非常小,我们可以通过一次n×\times×n的循环暴力比对每两个数字是否可以由这两种操作得到这张无环有向图的所有边。

#include<bits/stdc++.h>
#define ll long long
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;

vector<int>field[107];//保存图的边信息i点与field[i]中的元素存在有向边
ll num[107];
int n;
bool visit[107];//记录各个点被访问的情况
vector<int>road;//保存路径,用数组实现而不是使用vector的push和pop操作会更快,这里出于方便理解的考虑写成vector形式

void dfs(int now)
{
    visit[now]=1;//当前位置置为访问过
    road.push_back(now);//压入路径中

    if(road.size()==n)
    {
        for(int i=0;i<n;i++) cout<<num[road[i]]<<' ';
        exit(0);//找到满足的路径后直接结束程序
    }

    for(int i=0;i<field[now].size();i++)//遍历当前结点出发可以走到的其他点
        if(!visit[field[now][i]]) dfs(field[now][i]);//如果下个位置未被访问过,即未被走过的路径,继续递归搜索

    road.pop_back();//还原
    visit[now]=0;//还原
}

int main()
{
    IOS;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>num[i];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(num[j]*3==num[i]||num[i]*2==num[j])//暴力for一遍建图
                field[i].push_back(j);
    for(int i=1;i<=n;i++) dfs(i);//以这n个数字分别作为第一个数字进行搜索
}

我们进行的操作只有 ×\times× 2或者 ÷\div÷ 3
那么随着我们操作的进行,当前数字分解质因数后,2出现的次数是不断在上升的,而3出现的次数是不断在下降的。
依靠这一点直接sort一遍即可,第一排序关键字为分解质因数后3出现的个数,3个数相同的情况下直接比较数值大小即可,大的数值在后面。

#include<bits/stdc++.h>
#define ll long long
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;

struct Node
{
    ll num;//保存数值
    int base;//num分解质因数后3出现了几次
};

Node node[107];
int n;

bool cmp(Node a,Node b)
{
    if(a.base==b.base) return a.num<b.num;
    else return a.base>b.base;//排序的第一关键字为3出现的次数
}

int32_t main()
{
    IOS;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>node[i].num;
        ll temp=node[i].num;
        node[i].base=0;
        while(temp%3==0)
        {
            temp/=3;
            node[i].base++;
        }
    }
    sort(node,node+n,cmp);
    for(int i=0;i<n;i++) cout<<node[i].num<<' ';
}

E题
原题链接:https://atcoder.jp/contests/arc111/tasks/arc111_a
相关tag:数学,快速幂

注意到10n可以分解成k×\times×m2+d。(k和d均为整数)
其中k×\times×m2在经历/m%m的过程后必定为0,去除这部分对结果没有影响。
故我们直接用快速幂计算10n对m2取模的结果d,用d/m%m即为结果。

#include<iostream>
#include<algorithm>
#define ll long long
#define INF 0x7f7f7f7f //2139062143
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;

ll qpow(ll x,ll p,ll mod)//快速幂计算10^n%(m*m)的结果
{
    ll ret=1;
    while(p)
    {
        if(p&1) ret=ret*x%mod;
        x=x*x%mod;
        p>>=1;
    }
    return ret;
}

int main()
{
    IOS
    ll n,m;cin>>n>>m;
    n=qpow(10,n,m*m);
    cout<<n/m%m<<endl;
}

F题
原题链接:https://codeforces.com/problemset/problem/976/C
相关tag:排序,贪心

区间[l1,r1]完全包含区间[l2,r2]的充要条件是l1<=l2且r1>=r2。

对每个区间[l2,r2]来说,我们实际上只需要先找左边界l1<l2的所有区间与之对比,
或者l1=l2时,对比所有右区间r1>=r2的区间。

我们可以对所有区间进行一个排序,先按照左区间边界从小到大的顺序进行排序。
这样的话我们就保证了,对于第i个区间来说,左区间边界小于第i个区间的所有区间都在它的左侧。
当左区间边界相同时,按照右区间边界从大到小排序。
这样我们就保证了,左区间边界相等的所有区间,右区间边界大的在左侧。

之后直接从左到右for一遍,记录之前出现的最大右边界,与当前的右边界比较即可。

#include<bits/stdc++.h>
#define ll long long
#define INF 0x7f7f7f7f //2139062143
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
const int maxn=3e5+7;

struct Node//区间结构体,tar标记这是第几个区间,用于输出
{
    int l,r;
    int tar;
};

bool cmp(Node a,Node b)//sort的比较函数,左边界越靠左的排序后越在前,左边界相同情况下,右边界越靠右排序后越在前
{
    if(a.l==b.l) return a.r>b.r;
    else return a.l<b.l;
}

Node node[maxn];
int n;

int main()
{
    IOS
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>node[i].l>>node[i].r;
        node[i].tar=i+1;
    }
    sort(node,node+n,cmp);
    int pre=-1,r=0;//pre记录前面右边界最大的区间是第几个,r标记当前出现的最大右边界
    bool flag=0;
    for(int i=0;i<n;i++)
    {
        if(node[i].r<=r)
        {
            cout<<node[i].tar<<' '<<pre<<endl;
            flag=1;
            break;
        }
        else {pre=node[i].tar;r=node[i].r;}//更新右边界最大的区间以及最大右边界的值
    }
    if(!flag) cout<<-1<<' '<<-1<<endl;
}

G题
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1059
相关tag:dp,进制优化

我们把所有任务总共需要的天数记为sum。
这个题目一看是一个比较明显的多重背包问题,我们可以dp去求sum/2总天数的方案是否存在。
但是问题在于这里的背包个数x最多为2e4,而sum最多也有6e4。
而多重背包的复杂度为O(x×\times×sum/2),打到12e8,并且还有多组数据,因此直接多重背包dp是会tle的。

这里我们可以利用二进制分解任务的件数,将复杂度降低为O(logx×\times×sum/2)。
例如需要2天的任务有x2件,由于这些任务都是需要2天,可以被视作完全相同的任务。我们需要关注的只是这x2件任务需要选择几件。
而我们把这个x2件写成二进制,按照二进制的每一位单独拿出来,实际上就是x2的二进制各位取1还是取0,也就是取还是不取。
我们将x2的各个二进制位独立出来,视作统一的一件任务,自此转化为一个01背包问题。
而这个01背包拥有的背包数量len满足2len=x,故len=logx。

#include<stdio.h>
#include<string.h>
int sum,a[7],b[107],len;//sum为所有任务的天数综合,a[i]代表需要i天的任务有几件
bool dp[60001];
//b[]保存二进制优化的01背包
//dp[i]代表花费i天的分配方案是否存在

void get()
{
    sum=0;
    for(int i=1;i<=6;i++)
    {
        scanf("%d",&a[i]);
        sum=sum+i*a[i];
    }
}

void change()//二进制优化
{
    len=0;
    for(int i=1;i<=6;i++)//i代表当前优化的是需要i天的任务
    {
        int x=1;//对任务数量进行二进制分解,x从2进制最低位的1开始
        while(x<=a[i])
        {
            b[++len]=i*x;//x件任务合并为一个统一的任务
            a[i]-=x;
            x*=2;//二进制更高一位
        }
        if(a[i]) b[++len]=i*a[i];//剩余的部分合并为一个统一的任务
    }
}

int main()
{
    int flag,t=0;
    dp[0]=1;
    while(get(),sum)//逗号表达式,返回值为sum,当sum=0时推出循环;get函数负责读入
    {
        t++;//t记录当前是第几组数据
        flag=1;//标记是否存在平均分配的方案
        if(sum%2) flag=0;
        else
        {
            sum/=2;
            change();//将多重背包利用二进制优化为01背包
            for(int i=1;i<=len;i++)
                for(int j=sum;j>=b[i];j--)
                    if(dp[j-b[i]]) dp[j]=1;//01背包dp过程
            if(dp[sum]==0) flag=0;
            for(int i=1;i<=sum;i++) dp[i]=0;
        }
        printf("Collection #%d:\n",t);
        if(flag) printf("Can be divided.\n\n");
        else printf("Can't be divided.\n\n");
    }
}

H题
原题链接:
相关tag:树的直径,dfs

思路见注释

#include<bits/stdc++.h>
#define ll long long
#define INF 0x7f7f7f7f //2139062143
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
const int maxn=2e5+10;

//题意为给你一个有n个节点n-1条边的树(没有闭环的图)
//要求你在这棵树里找到三个节点,使得它们之间的三条路径走过的边数最多(多次经过同一条边只算一次)
//首先要知道树的直径这个概念.树的直径是整棵树中两点距离最长的那一条路径

//先用反证的方法证明三条路径必定至少有一条会是树的直径
//如果三条路径中没有任何一条是树的直径
//我们可以将其中的两个点更换为树的直径两端的端点,会发现长度变得更大了
//因此三条路径中没有任何一条是直径的情况必然不是总长度最长的

//因而首先我们可以确定这三条路径中必定至少存在一条直径,这样就确定了两个点,再就是第三个点如何确定
//第三个点和第一还有第二个点的路径合起来的新路径,必定包含了这条直径
//那么在原来已经找到的这条直径基础上加上这个第三个点,规定第三和第一个点的距离为d1,第三和第二个点的距离为d2,树的直径为x
//那么加入第三个点后增加的边数就应该是(d1+d2-x)/2,而x是我们计算出的一个定值
//所以实际上第三个点需要满足的条件是和第一个点还有第二个点的距离和最大

//到此思路已经全部完成,首先是求取树的直径的两个端点,这个方法和证明过程自己见算法书或者博客
//dfs第一次从1点开始,dst[i][0]记录i点到1点的距离,距离最大的点为直径的第一个端点a
//dfs第二次从a点开始,dst[i][1]记录i点到a点的距离,距离最大的点为直径的第二个端点b
//dfs第三次从b点开始,dst[i][2]记录i点到b点的距离,由此我们便计算出了整棵树各个点到点a还有点b的距离,由此去寻找c点

vector<int>road[maxn];//记录路径
int dis[maxn][3];

void dfs(int now,int before,int sum,int cas)//now为当前所在节点位置,before为上一个节点位置,sum为当前到起点的距离,cas为dst第二个下标
{
    for(int i=0;i<road[now].size();i++)
    {
        if(road[now][i]!=before)         //这是个无闭环的图,因此我们任意的搜索路径也都是无闭环的,只要满足不往回走就可以了
        {
            dis[road[now][i]][cas]=sum+1;
            dfs(road[now][i],now,sum+1,cas);
        }
    }
}

int main()
{
    IOS
    memset(dis,0x7f,sizeof(dis));
    int n;
    cin>>n;
    for(int i=1;i<n;i++)
    {
        int x,y;
        cin>>x>>y;
        road[x].push_back(y);
        road[y].push_back(x);
    }
    dis[1][0]=0;
    dfs(1,1,0,0);
    int a,b,c,Max=-INF;
    for(int i=2;i<=n;i++)
        if(dis[i][0]>Max)
        {
            Max=dis[i][0];
            a=i;
        }
    dis[a][1]=0;
    dfs(a,a,0,1);
    Max=-INF;
    for(int i=1;i<=n;i++)   //这个循环结束后Max记录的便是直径的长度
    {
        if(dis[i][1]>Max)
        {
            Max=dis[i][1];
            b=i;
        }
    }
    dis[b][2]=0;
    dfs(b,b,0,2);
    int ans=-INF;
    for(int i=1;i<=n;i++)       //ans记录的是c点到a点和b点的距离和
    {
        int x=dis[i][1]+dis[i][2];
        if(x>ans&&i!=a&&i!=b)  //注意这里如果整棵树只有一条路径的话寻找c点的时候可能会和a或者b点重复
        {
            ans=x;
            c=i;
        }
    }
    ans=(ans+Max)/2;            //原本应该是(ans-Max)/2+Max,化简了一下
    cout<<ans<<endl;
    if(a>b) swap(a,b);
    if(b>c) swap(b,c);
    if(a>b) swap(a,b);
    cout<<a<<' '<<b<<' '<<c<<endl;
}
GAMES101:MacOS作业环境搭建 查看gcc/clang的位置产看gcc/clang的版本1.1.2 安装cmake。 阅读详情

相关推荐

知识导航神器:Obsidian Breadcrumbs 插件全攻略

Parent: 插件Child: Breadcrumbs 用法这样,它就能识别出你和其他笔记的关系。

m0_73735578的博客 1630

ZAFU寒假个人赛2022.01.22 A~H 题解

ZAFU寒假个人赛2022.01.22 A~H 题解 A - Weird Function(AtCoder - abc234_a) 思路: 直接调用函数即可,签到。 参考代码: #include<bits/stdc++.h> using namespace std; #define mp make_pair #define int long long #define re register int #define pb emplace_back #define lowbit(x) (x

qq_53504307的博客 668

原神真端,原神服务端,虚拟机启动部署傻瓜式教学

没玩过抽卡 游戏想体验一下抽卡的感觉,听说原神有真端了,所以弄一个局域网的服务体验一下,这里要感谢一些服务端的分享者。

azyouyouyou的博客 1万+

ZAFU_2021_1_26_2021寒假个人赛第二场题解

A题 原题链接:https://codeforces.com/problemset/problem/884/A 相关tag:施行 每天有86400秒,写了x秒的作业,还有86400-x秒可以练歌。(还是很想吐槽这个不需要睡觉的设定) 直接一天天的依次算过去,哪一天练得时间足够了就输出。 #include<bits/stdc++.h> #define ll long long #define INF 0x7f7f7f7f //2139062143 #define llINF 92233720368

StandNotAlone的博客 1758

【科研学习】Demo3D2015安装包以及图文安装步骤

安装包 点击下图的.exe文件,安装 不需要解压,打开注册机 如下图: 点击上图的.exe文件,出现下图 先点击 patch 打开安装目录下的Demo3D.licensing.dll文件,然后点击Generate,生成dvt-license文件,保存即可 打开安装完成的Demo3D 2015(64-bit),一般破解没完成的,会出现一个request a license 的问题,点击find license 的那一行 点击后找到自己Generate,生成dvt

KaelCui的博客 1万+

AUTOSAR CAN通信全过程

首先,从AUTOSAR架构上来说,一个完整的CAN通信的过程涉及到了包括硬件、AUTOSAR中间件和上层应用层软件;在硬件部分来说,涉及到的是CAN 总线和CAN的收发器;软件部分的话,涉及到的概念是MCAL(微控制器抽象层)、BSW(基础软件层)、RTE(实时运行环境)、APPL(应用层)等;其中MCAL部分用到了通信驱动模块,而BSW部分使用到了通信服务模块和通信硬件抽象模块;由于笔者是做MCAL和BSW的,至于应用层部分的知识就暂且不具体介绍了;

xxdw1992的博客 6253

ZAFU_2021_1_24_2021寒假个人赛第一场题解

题目的解法不一定唯一,这里给出我自己个人过题时使用的解法。 A题 原题链接:https://codeforces.com/problemset/problem/1370/A 相关tag:规律总结 我们要选择两个不同的数,使得他们的最大公约数尽可能大。 假设我们已经找到了第一个数为x,那么第二个数选择x的整数倍的话,他们的最大公约数都是x。 但是题目已经说了必须选两个不同的数,因此我们选择x和2x,此时最大公约数为x。 2x要满足小于等于n,因此x的最大值就是n/2 #include<bits/stdc

StandNotAlone的博客 2547

dbt+Snowflake实战:数据建模、权限隔离与性能优化全指南

dbt(data build tool)作为现代数据栈的核心建模工具,其与Snowflake的深度协同远不止于SQL编译执行——它本质是将软件工程实践(如版本控制、测试驱动、CI/CD)注入数据交付流程。理解dbt的声明式建模原理与Snowflake的虚拟仓库、Time Travel、TRANSIENT表、聚簇键等底层机制如何咬合,是实现可维护、可审计、低成本数据产品交付的关键。本文聚焦dbt在Snowflake环境中的真实落地挑战,涵盖schema与warehouse的物理映射设计、role级硬隔离策略、

weixin_34389926的博客 314

ZAFU_2021_2_17_2021寒假个人赛第四场题解

A题 原题链接:https://codeforces.com/problemset/problem/1296/A 相关tag:简单思维 我们每次操作可以把数组中的一个数变为另一个数,那么如果这两个数同为奇数或者同为偶数的话,操作后是不会对整个数组总和的奇偶性造成影响的。只有奇数变为偶数或者偶数变为奇数的时候,才会对整个数组总和的奇偶性造成影响。 那么我们可以统计出原数组中奇数的个数记为num1,偶数的个数记为num2。 整个数组总和的奇偶性是由奇数的个数决定的,当num1为奇数的时候,整个数组的总和一开始就

StandNotAlone的博客 2781

驯服电源尖峰:从BUCK/BOOST环路剖析到高di/dt噪声的实战抑制

本文深入探讨了电源系统中高di/dt噪声的产生机制及抑制方法,通过BUCK/BOOST电路的环路分析,揭示了电流路径不连续导致的电压尖峰问题。文章提供了实用的PCB布局技巧和噪声抑制策略,包括最短回路原则、铺铜优化和过孔阵列战术,帮助工程师有效降低EMI噪声,提升电源系统的稳定性。

weixin_29587015的博客 273

Auto.js实战:从解锁手机到自动阅读的全流程避坑指南(MIUI系统适配版)

本文详细介绍了Auto.js在MIUI系统下的自动化操作全流程优化指南,包括设备唤醒、应用启动、界面交互等关键环节的实战技巧。特别针对MIUI系统的变速检测机制和电源管理策略,提供了有效的避坑方案和性能优化建议,帮助开发者实现从解锁手机到自动阅读的稳定运行。

醉三国 246

浙江农林大学ACM集训队2019级队长退役回忆录(未实际退役版本)

某个弱校集训队队长的退役回忆录

StandNotAlone的博客 8775

Allegro输出光绘文件规范

添加钻孔表的具体步骤为:1.通过屏幕右边的Visibility选项的Views列表,将Drill层打开2.将Visibility选项中的PIN和Via选项都选中,见下图所示: 参数设好之后关闭NC Drill/Parameters窗口,输出数控机床钻孔文件的命令菜单为:Manufacture=>NC=>NC Drill…,打开的窗口如下: 输出数控机床钻孔文件的具体步骤为: 上图是光绘输出的层控制窗口,还有一个窗口是输出参数的控制窗口,我们通过点击上图的第二个列表项General Parameters来

axingxiansen的博客 2808

浙江农林大学acm集训队,2023级队长退役回忆录

之前备赛的时候经常看学长们的退役文章,看着前辈们光辉的历史总是幻想自己也能站在同样的地方,获得同样的奖牌。回想 2 年前初出茅庐的我,那个连自己为什么在打比赛都没有搞清楚的我,全然不知自己也会成为队长,自己也会拿下和学长们一样的奖牌,自己也能成为教练过了很久之后也会提及的对象。全然不知 ACM 会成为我人生中相当美好的一段经历。现在轮到我自己来写了,事情的起因是这样的:那天和队友们看了19级队长的退役文章,对其传奇的经历和轻小说一般的文笔感触很深。

2401_84209272的博客 1713

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

视频隐私脱敏工程化:CSRT/KCF追踪算法在本地推理中的实现与边界

在短视频内容合规审查中,动态遮挡(Dynamic Masking)是高频且高耗时的环节。传统手动关键帧打码不仅效率低下,且在目标快速移动或遮挡时极易出现遮罩漂移。本文从计算机视觉工程角度,解析基于CSRT与KCF算法的目标追踪方案在视频隐私处理中的技术路径、性能权衡及落地实践。

Mysssone的博客 203

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

【算法拾光】链表 哈希表|K个一组翻转链表 + 两数之和

K个一组翻转链表需分段反转,借助哑节点与前驱指针维护连接,避免断链;两数之和利用哈希表实现O(1)查找,空间换时间,高效定位目标组合。前者考察链表指针操作,后者聚焦映射关系构建,均为面试高频题。

wuqingyigexiaoba的博客 312

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

排序算法深度笔记(下):非比较类排序的线性突破与工程边界

排序算法时间复杂度额外空间复杂度稳定性是否基于比较选择排序O(N^2)(O(1))不稳定是冒泡排序O(N^2)(O(1))稳定是插入排序O(N^2)(O(1))稳定是归并排序O(N\log N)(O(N))稳定是快速排序O(N\log N)O(log N)不稳定是堆排序O(N\log N)O(1)不稳定是计数排序(O(N + M))O(M))稳定否基数排序O(N)稳定否桶排序平均O(N) / 最坏O(N^2)

2401_87069538的博客 571

算法日常・每日刷题--<动态规划>42

本题为“不相交的线”,与最长公共子序列问题相似。使用动态规划求解:定义 dp[i][j] 表示 nums1[0:i] 与 nums2[0:j] 的最大不相交连线数。若元素相等,则继承左上值加1;否则取上方或左方最大值。最终返回 dp[m][n],即两数组的最大不相交连线数。时间复杂度 O(mn),空间复杂度 O(mn)。

2503_92261635的博客 20

C语言程序设计题|有序数组插入数字冒泡排序

题目要求将一个数插入有序数组末尾,并用冒泡排序实现整体升序。代码先将输入数存入数组最后位置,再通过双重循环进行冒泡排序,每轮将较大元素向后移动,最终输出11个升序元素。该方法虽时间复杂度为O(n²),但符合题目要求,逻辑清晰,适合初学者理解排序原理。

2301_81429079的博客 749

【算法拾光】模拟|外观数列 + 数青蛙

本文总结两道模拟题解法:外观数列通过迭代统计连续数字个数生成下一项,关键在于处理末尾字符;数青蛙则模拟青蛙叫声“croak”状态转移,维护各阶段青蛙数量,记录最大并发数并确保全部完成。共性在于严格遵循流程、细致处理边界与非法情况,锻炼字符串遍历与状态管理能力。

wuqingyigexiaoba的博客 367

牛客周赛165C题(前后缀性质,递推,排序,枚举)

题目大意:给定长度为 `n` 的数组,选择 `k ∈ [1,n]`,将前 `k` 个元素整体翻转,后面的元素不变。要求操作后的整个数组非递减,统计满足条件的 `k` 的数量。题目链接:https://ac.nowcoder.com/acm/contest/141721/C。时间复杂度:O(nlogn)

2501_94316951的博客 170

【数据结构-3】算法美学之降复杂度

在while循环的循环体内,首先用临时变量保存最后一个位置的数据,再通过for循环把所有元素往后移动一位,最后把tmp中保存的值放到下标为0的位置上去。方法二的思路是:创建新数组,让原数组中后k个数据移动到新数组中前面的位置,让原数组中前numsSize-k个数据移动到新数组中后面的位置,这。这段代码的思路是:三次逆置,第一次逆置前numsSize-k个数据,第二次逆置后k个数据,最后整体逆置。这篇博文分享一道解法不一的算法题,求解过程的目的在于降低算法的时间复杂度,题源力扣。,属于空间换时间的操作。

weixin_44218929的博客 83

算法61,判定是否为字符重排

两字符串能互为重排 ⇔。

sheshibenniaodan的博客 217

算法日常・每日刷题--<动态规划>32

给定严格递增的正整数数组,求最长斐波那契子序列长度。使用二维DP,dp[i][j]表示以arr[i]、arr[j]为最后两项的序列长度,初始化均为2。通过哈希表快速查找前一项target = arr[j] - arr[i],若存在且下标小于i,则状态转移:dp[i][j] = dp[k][i] + 1。遍历更新全局最大长度,最终若结果小于3则返回0。时间复杂度O(n²),空间复杂度O(n²)。

2503_92261635的博客 178

算法札记:几何分布在算法题UVA1262的运用

集卡问题求解核心:将集齐n种优惠券的过程分为n个阶段,每个阶段期望购买次数为 $ \frac{n}{k} $(k为剩余种类数),总期望为 $ n \cdot H_n $(调和数)。通过自洽方程推导单阶段期望,无需几何分布或无穷级数,逻辑清晰且适用于大一水平。例如,n=5时期望约11.42,非5。题目要求以带分数形式输出精确结果,算法上需累加分数并化简。

Keven_11的博客 349

不同的二叉搜索树

互不相同的二叉搜索树的种数,以 j (1<=j<=i)为头节点,左子树是 j-1 个数,右子树就是 i - (j - 1) -1 = i - j个数。所以dp[3] = dp[0] * dp[2] + dp[1] * dp[1] + dp[2] * dp[0]头1 = 左子树0节点 * 右子树2节点,二叉搜索树就是排序树,左子树<根节点<右子树,左右子树也满足左子树<根节点<右子树。头2 = 左子树1节点 * 右子树1节点。所以dp[i] += dp[j-1] * dp[i-j]个节点组成且节点值从。

qq_44721738的博客 152
上一篇: ZAFU_2021_1_26_2021寒假个人赛第二场题解
下一篇: Codeforces Round #697 (Div. 3)A-G题解
StandNotAlone
博客等级 码龄7年 338粉丝 47原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值