AtCoder ABC332 题解A-F

Atcoder ABC285 赛后总结 新鲜出炉,制作不易 阅读详情

前言

这场比赛跟之前的ABC比赛比起来难度还是要高不少,前面的几题也没有之前的比赛那么签,中间的中档题也要难不少(个人感觉),下面的题解,我赛时过了的题我会尽量讲一下我做题时候的心理过程,是如何想出答案的,赛时没过但是后面补题了的题,我就尽量讲一下我对于题解的理解。

A.Online Shopping(模拟)

考察英语阅读理解
这题还是比较简单,就是网购,告诉我们要买的每个物品的数量和价格,以及满多少钱包邮,问最后付的钱多少,直接按题意模拟即可。

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e5+10;
int p[maxn],q[maxn];
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int n,s,k;cin>>n>>s>>k;
    int tot=0;
    for(int i=1;i<=n;i++){
        cin>>p[i]>>q[i];
        tot+=p[i]*q[i];
    }
    if(tot<s) tot+=k;
    cout<<tot<<endl;
    return 0;
}

B.Glass and Mug(模拟)

题意

给我们玻璃杯和马克杯,然后有三种跟倒水相关的操作,总共执行 k k k次,问 k k k次后最终玻璃杯和马克杯还剩多少水。

分析

同样按照题意模拟这三种操作,可以用两个变量来记录当前的玻璃杯和马克杯的水量,然后三种操作就对应对这两个变量进行操作。不过要注意 i f if if语句的顺序一定要按照它给的三种操作顺序,(一开始没看懂第一种操作,我就先 i f if if第二种情况,后面再 e l s e i f else if elseif第一种情况,样例没过,才注意到一定要按照给的顺序判断)

代码

#include<bits/stdc++.h>
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int n,G,M;cin>>n>>G>>M;
    int g=0,m=0;
    for(int i=1;i<=n;i++){
        if(g==G){
            g=0;
        }
        else if(!m){
            m=M;
        }
        else{
            int tem=min(G-g,m);
            m-=tem;
            g+=tem;
        }
    }
    cout<<g<<" "<<m<<endl;
    return 0;
}

C.T-shirts(贪心)

题意

这题是真正的阅读理解
给一个含012的字符串,有两种衣服一般的和豪华的,一开始有 m m m件一般的衣服,1和2代表两种活动,1的活动两种衣服都可以穿,2的活动只能穿豪华衣服,0代表洗衣服,即两种衣服的数量恢复到原有的数量,问最少需要买多少件衣服才能满足活动需要

分析

首先因为豪华衣服在两种活动都能穿,所以贪心地想,要买衣服肯定买的是豪华衣服。然后字符串里每次遇到0就会重置衣服数量,所以肯定要以0为分界线,分成若干个段,满足最少买衣服数量且能满足这些段的要求。
然后赛时我一下子脑抽了,没想到在不确定买多少件衣服的情况下要怎么做,就写了个二分,二分购买豪华衣服的数量再 O ( n ) O(n) O(n),然后就可以简单地遍历模拟是否符合条件。
正解是直接统计0划分出的若干个段中,1、2活动的数量分别为 x x x, y y y,然后因为开始一件豪华衣服也没有,所以至少要买的数量大等于 y y y,而且如果活动1过多,自己原有的普通衣服不够穿,那么还需要买豪华衣服使得活动1也够穿,也就是购买的豪华衣服数量大等于 x + y − m x+y-m x+y−m,所以答案就是若干段中的 m a x ( x + y − m , y ) max(x+y-m,y) max(x+y−m,y)的最大值。

代码(二分)

#include<bits/stdc++.h>
using namespace std;
int n,m;string str;
bool check(int mid){
    int s=m,p=mid;
    for(auto c:str){
        if(c=='0'){
            s=m;p=mid;
        }
        else if(c=='1'){
            if(s) s--;
            else if(p) p--;
            else return 0;
        }
        else{
            if(p) p--;
            else return 0;
        }
    }
    return 1;
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n>>m;
    cin>>str;
    int l=0,r=1e3,ans=0;
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid)) ans=mid,r=mid-1;
        else l=mid+1;
    }
    cout<<ans<<endl;
    return 0;
}

D.Swapping Puzzle(枚举/全排列)

题意

给两个 n ∗ m n*m n∗m的二维矩阵 ( n , m ≤ 5 ) (n,m\leq 5) (n,m≤5),可以执行若干次操作,每次操作将第一个矩阵的相邻两行或者相邻两列进行交换,问将矩阵一变成矩阵二至少需要经过多少次操作,或者不可能使矩阵一变成矩阵二。

分析

赛时这题没做出来,不过还是讲一下我赛时的心路历程。
我先去观察,交换行列对矩阵的影响是什么。会发现假如只交换列,那么对于行来说,下标相同的元素都是一块变换的,也就是同一行的元素只是在同一行内部移动,不会跑到其他行。同理交换行,对于每一列来说,元素只在每一列内部移动不会跑出去。
就算两种操作结合起来,依旧如此,所以判定是否有解的情况,我想的就是,能否将矩阵一的每一行对应矩阵二的某一行,并且满足这两行中的元素对应大小的数量相同,也就是矩阵二的这一行能够由矩阵一的这一行交换后得到。然后由这种交换得到一种次序映射关系,将矩阵二的这一行设为 1 , 2 , 3 , 4 , 5 1,2,3,4,5 1,2,3,4,5,得到矩阵一的这一行对应为 2 , 1 , 4 , 5 , 3 2,1,4,5,3 2,1,4,5,3(举例)等等,然后其他行也都能够对应映射到不同的某一行,且映射的数字也要为 2 , 1 , 4 , 5 , 3 2,1,4,5,3 2,1,4,5,3,代表这一种映射是有效的,有解。
但是会发现上面讲的这种匹配方法太麻烦,而且如果有重复数字的话也会不知道该将哪两个数字进行匹配。所以这题就卡在这里了,赛后看了题解恍然大悟。
正解不是通过矩阵一和矩阵二的元素去进行匹配,而是去枚举第二个矩阵所有行列交换后可能得到的矩阵,再检验矩阵一和矩阵二是否满足这种枚举的匹配。
对于行来说,所有行的排列方式为 n ! n! n!种,列同理为 m ! m! m!,我们相当于是去将矩阵二的行列所有可能的交换形式后得到的新矩阵去跟矩阵一匹配,而这所有可能的交换形式最多也就是 n ! ∗ m ! n!*m! n!∗m!即 125 ∗ 125 125*125 125∗125种。
PS:枚举全排列可以用c++的next_permutation()函数,不用写dfs,具体使用方法可以去搜一下,或者直接看我代码里面的用法。
具体的这种操作方法就可以开两个数组 r o w [ n ] row[n] row[n]和 c o l [ m ] col[m] col[m],分别表示矩阵二的第 i i i行,对应交换后得到的新矩阵第 r o w [ i ] row[i] row[i]行,以及矩阵二的第 j j j行,对应交换后得到新矩阵的第 c o l [ i ] col[i] col[i]列。
然后我们要做的就很简单了,就是检查这个新矩阵是否和矩阵一相等,直接 O ( n 2 ) O(n^2) O(n2)的遍历矩阵一,一个一个元素检查即可(发现有一个元素不满足直接 b r e a k break break,可以优化一点时间)
然后假如已经得到可以匹配了,代表一定有解,又该如何求总操作次数呢?我们不妨把行、列分开,因为行列之间的交换互不影响,那么单单看行,想要交换回去,其实就相当于把我们枚举到的排列 2 , 1 , 4 , 5 , 3 2,1,4,5,3 2,1,4,5,3通过相邻元素交换,使其变回 1 , 2 , 3 , 4 , 5 1,2,3,4,5 1,2,3,4,5,那么这不就是经典的冒泡排序吗?所以我们就可以知道操作次数就等于排列的逆序对数,再 O ( n 2 ) O(n^2) O(n2)的遍历统计枚举的排列的逆序对数即可。
将每一种可能的枚举排列的行、列的逆序对数相加,取 m i n min min,即为最终答案。总的时间复杂度是 O ( n ! ∗ m ! ∗ n ∗ m ) O(n!*m!*n*m) O(n!∗m!∗n∗m),因为 n , m ≤ 5 n,m\leq 5 n,m≤5所以复杂度是可以通过的。

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e1;
int a[maxn][maxn],b[maxn][maxn];
int main(){
	int n,m;cin>>n>>m;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			cin>>a[i][j];
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			cin>>b[i][j];
	int row[6],col[6];
	//初始化枚举的行列排列
	for(int i=1;i<=n;i++)
		row[i]=i;
	for(int i=1;i<=m;i++)
		col[i]=i;
	int ans=1e9;
	do{
		do{
			int flag=1;//表示这次枚举能否匹配
			for(int i=1;i<=n;i++)
				for(int j=1;j<=m;j++)
					flag&=(a[row[i]][col[j]]==b[i][j]);
					//有一个元素不等,&后flag就会为0
			if(!flag) continue;//不匹配则跳过该次枚举
			int tem=0;
			for(int i=1;i<=n;i++)
				for(int j=i+1;j<=n;j++)
					tem+=row[i]>row[j];//统计逆序对数
			for(int i=1;i<=m;i++)
				for(int j=i+1;j<=m;j++)
					tem+=col[i]>col[j];
			ans=min(ans,tem);
		}while(next_permutation(row+1,row+1+n));//全排列枚举
	}while(next_permutation(col+1,col+1+m));
	if(ans==(int)1e9) ans=-1;//说明一个匹配都找不到
	cout<<ans<<endl;
	return 0;
} 

E.Lucky bag(状压dp)

题意

有 N N N个物品,将其装入 D D D个袋子,袋子可以为空,求通过合理分配,所有袋子重量的最小方差。数据范围 2 ≤ D , N ≤ 15 2\leq D,N\leq 15 2≤D,N≤15

分析

看到数据范围应该要去猜这题是状压 d p dp dp,然后考虑如何设计状态。
在这之前,先去看一下题目要求的是什么。方差 S 2 = 1 D ∑ i = 1 D ( x i − x ‾ ) 2 S^2=\frac{1}{D}\sum_{i=1}^{D}{(x_i-\overline{x})^2} S2=D1​i=1∑D​(xi​−x)2
对于给定的那些物品,每个袋子的平均重量 x ‾ \overline x x是确定了的 ∑ x i / D \sum x_i/D ∑xi​/D,所以我们可以考虑设计状态 d p [ i ] [ j ] dp[i][j] dp[i][j]表示将状态 i i i表示的几个数字,装入 j j j个袋子,使得 ∑ ( x i − x ‾ ) 2 \sum (x_i-\overline x)^2 ∑(xi​−x)2最小的值(不直接把除以 D D D也带上是因为如果中间就除以 D D D了,过程的状态转移就不好写了,所以放到最后再除)。那么最终要求的答案明显就是 d p [ 11...1 ] [ D ] / D dp[11...1][D]/D dp[11...1][D]/D,即将所有的物品装入 D D D个袋子使得 ∑ ( x i − x ‾ ) 2 \sum (x_i-\overline x)^2 ∑(xi​−x)2最小,再除以 D D D,就是最终的最小方差。
这里状态设计感觉不是很好想,不过按我个人经验, d p dp dp题经常可以从结果来逆推,如这题可以根据最终要的方差的形态来构造 d p dp dp数组,再去尝试推 d p dp dp数组的递推关系。
然后来考虑状态转移的过程,对于 d p [ S ] [ i ] dp[S][i] dp[S][i],我们考虑它是由哪些状态转移过来的。
将 S S S里的物品放入 i i i个袋子,可以考虑先将 S S S里的部分物品 T T T( T ∈ S T\in S T∈S)放入 i − 1 i-1 i−1个袋子( d p dp dp中也经常是相邻两个 i i i之间进行转移)对应的贡献为 d p [ T ] [ i − 1 ] dp[T][i-1] dp[T][i−1],再将剩下的物品 T − S T-S T−S放入一个袋子,对应贡献 d p [ T − S ] [ 1 ] dp[T-S][1] dp[T−S][1],它们之间的贡献是可以直接相加的(这个地方我觉得是个重点,也是状态转移的核心)
所以就可以得到状态转移方程式为 d p [ S ] [ i ] = m i n { d p [ T ] [ i − 1 ] + d p [ T − S ] [ 1 ] } , ∀ T ∈ S dp[S][i]=min\{dp[T][i-1]+dp[T-S][1]\},\forall T\in S dp[S][i]=min{dp[T][i−1]+dp[T−S][1]},∀T∈S
而所有的物品可能,放入一个袋子的 ∑ ( x i − x ‾ ) 2 \sum (x_i-\overline x)^2 ∑(xi​−x)2可以轻松地算出来,也就是初始化 d p [ S ] [ 1 ] dp[S][1] dp[S][1],然后就可以状压 d p dp dp递推了。
这里还有一个知识点,就是对于 S S S,该如何去枚举子集 T T T,这里涉及到一个二进制子集枚举的知识点,有一个结论一样的,就是如果已知二进制 S S S,那么枚举子集 T T T就是不断地令 T = ( T − 1 ) & S T=(T-1)\&S T=(T−1)&S, T T T就可以遍历所有的 S S S子集。
考虑时间复杂度,因为所有的状态有 2 n 2^n 2n,对于有 i i i个元素的集合,子集数量为 2 i 2^i 2i,相乘后再一顿 ∑ \sum ∑,由二项式定理合并起来,反正最后是 O ( 3 n ∗ D ) O(3^n*D) O(3n∗D)
细节见代码

代码

#include<bits/stdc++.h>
#define db double
using namespace std;
const int N=16;
db arr[N],dp[1<<N][N];
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    memset(dp,0x7f,sizeof(dp));//初始赋极大值
    int n,d;cin>>n>>d;
    db ave=0;
    for(int i=0;i<n;i++) cin>>arr[i],ave+=arr[i];
    ave/=d;//计算平均数
    for(int i=0;i<(1<<n);i++){
        db sum=0;
        for(int j=0;j<n;j++)
            if(i&(1<<j)) sum+=arr[j];
        dp[i][1]=pow(sum-ave,2);//初始化所有放入1个袋子的最小值
    }
    for(int i=2;i<=d;i++){
        for(int j=0;j<(1<<n);j++){//枚举所有二进制状态
            for(int k=j;k;k=(k-1)&j){//枚举状态j的所有子集
                dp[j][i]=min(dp[j][i],dp[j-k][i-1]+dp[k][1]);
            }
        }
    }
    db ans=dp[(1<<n)-1][d]/d;
    cout<<fixed<<setprecision(15)<<ans<<endl;
    return 0;
}

F.Random Update Query(线段树)

题意

给一个数组,有多次操作,每次操作 L i , R i , X i L_i,R_i,X_i Li​,Ri​,Xi​,表示将数组中 L i 到 R i L_i到R_i Li​到Ri​的区域等可能地选其中一个赋值为 X i X_i Xi​,即对 ∀ i ∈ [ L i , R i ] \forall i\in [L_i,R_i] ∀i∈[Li​,Ri​],有 1 R i − L i + 1 \frac{1}{R_i-L_i+1} Ri​−Li​+11​的概率使 a r r [ i ] = X i arr[i]=X_i arr[i]=Xi​。求最终数组里每一个元素的期望值是多少。

分析

先去考虑每一次操作对于数组元素期望值的影响。
假如原先数组里 a r r [ i ] = a arr[i]=a arr[i]=a,然后进行了一次操作 i , i + 2 , b i,i+2,b i,i+2,b,根据题意,数组里第 i i i个和第 i + 1 i+1 i+1 i + 2 i+2 i+2个元素各有 1 3 \frac{1}{3} 31​的可能变为 b b b,对于 a r r [ i ] arr[i] arr[i]而言,就是有 1 3 \frac13 31​的可能变成 b b b,还有 1 − 1 3 = 2 3 1-\frac13=\frac23 1−31​=32​的可能保持不变仍是 a a a。
那么根据期望的定义,这一次操作后, a r r [ i ] arr[i] arr[i]的期望值就等于 ∑ x i ∗ p i \sum x_i*p_i ∑xi​∗pi​等于 1 3 ∗ b + 2 3 ∗ a \frac13*b+\frac23*a 31​∗b+32​∗a。
通过手算这一个例子,不难看出,对于一次操作 L i , R i , X i L_i,R_i,X_i Li​,Ri​,Xi​,对于数组期望的影响就是对于区间 [ L i , R i ] [L_i,R_i] [Li​,Ri​],先乘上 ( 1 − 1 R i − L i + 1 ) (1-\frac{1}{R_i-L_i+1}) (1−Ri​−Li​+11​)(这里还需要用逆元化除为乘),即乘上 ( R i − L i ) ∗ ( R i − L i + 1 ) m o d − 2 (R_i-L_i)*(R_i-L_i+1)^{mod-2} (Ri​−Li​)∗(Ri​−Li​+1)mod−2,也就是算出这一次操作后不变的期望,至于变化后的期望,由于都是 1 R i − L i + 1 ∗ X i \frac{1}{R_i-L_i+1}*X_i Ri​−Li​+11​∗Xi​,所以相当于再给这个区间内所有数加上这个值。
所以我们需要一种能够快速给区间加上某个数,乘上某个数的数据结构,结合数据范围 N , M ≤ 2 ∗ 1 0 5 N,M\leq 2*10^5 N,M≤2∗105,显然可以用线段树解决!
而且刚好洛谷里【模板】线段树2这道题就要求我们实现区间加和区间乘,所以可以直接用这道题的数据结构来实现。

代码

#include<bits/stdc++.h>
#define int long long
#define ll long long
#define pii pair<int,int>
#define inf 0x3f3f3f
const int maxn=2e5+10;
using namespace std;
ll arr[maxn];
int mod=998244353;
struct tree{
    ll l,r;//区间左右端点
    ll sum=0,laz1=0,laz2=1;//当前结点的值和懒标记
}t[4*maxn+2];
int ksm(int a,int b){
    int res=1;
    for(;b;b>>=1,a=a*a%mod)
        if(b&1) res=res*a%mod;
    return res;
}
void build(int p,int l,int r,int mod){//建树
    t[p].l=l;t[p].r=r;
    t[p].laz1=0;
        t[p].laz2=1;
    if(l==r){//是叶子结点
        t[p].sum=arr[l];
        return;
    }
    int mid=l+r>>1;
    build(p*2,l,mid,mod);
    build(p*2+1,mid+1,r,mod);
    t[p].sum=(t[p*2].sum+t[p*2+1].sum)%mod;//当前节点的值等于两个孩子的值的和
} 

void spread(int p,int mod){
        t[p*2].sum=(t[p*2].sum*t[p].laz2+t[p].laz1*(t[p*2].r-t[p*2].l+1))%mod;//更新孩子用懒标记修正后的值
        t[p*2+1].sum=(t[p*2+1].sum*t[p].laz2+t[p].laz1*(t[p*2+1].r-t[p*2+1].l+1))%mod;
        t[p*2].laz2=t[p*2].laz2*t[p].laz2%mod;//将该结点的懒标记传给孩子
        t[p*2+1].laz2=t[p*2+1].laz2*t[p].laz2%mod;
        t[p*2].laz1=(t[p*2].laz1*t[p].laz2+t[p].laz1)%mod;
        t[p*2+1].laz1=(t[p*2+1].laz1*t[p].laz2+t[p].laz1)%mod;
        t[p].laz1=0;//清空当前结点的懒标记
        t[p].laz2=1;//清空当前结点的懒标记
}
void change(int p,int l,int r,int k,int mod){//区间增加k
    if(l>t[p].r||r<t[p].l) return;
    if(l<=t[p].l&&r>=t[p].r){//如果要修改的区间覆盖了当前结点表示的区间
        t[p].sum+=(ll)k*(t[p].r-t[p].l+1)%mod;
        t[p].laz1=(t[p].laz1+k)%mod;
        return;
    }
    spread(p,mod);//检测懒标记
    int mid=t[p].l+t[p].r>>1;
    if(l<=mid) change(p*2,l,r,k,mod);//如果要修改的区间覆盖了左儿子,就修改左儿子
    if(r>mid) change(p*2+1,l,r,k,mod);//右儿子同理
    t[p].sum=(t[p*2].sum+t[p*2+1].sum)%mod;//最终维护的值等于左儿子的值+右儿子的值  
}
void change2(int p,int l,int r,int k,int mod){//区间乘法
    if(l>t[p].r||r<t[p].l) return;
    if(l<=t[p].l&&r>=t[p].r){//如果要修改的区间覆盖了当前结点表示的区间
        t[p].sum=(t[p].sum*k)%mod;
        t[p].laz2=(t[p].laz2*k)%mod;
        t[p].laz1=(t[p].laz1*k)%mod;
        return;
    }
    spread(p,mod);//检测懒标记
    int mid=t[p].l+t[p].r>>1;
    if(l<=mid) change2(p*2,l,r,k,mod);//如果要修改的区间覆盖了左儿子,就修改左儿子
    if(r>mid) change2(p*2+1,l,r,k,mod);//右儿子同理
    t[p].sum=(t[p*2].sum+t[p*2+1].sum)%mod;//最终维护的值等于左儿子的值+右儿子的值  
}
ll ask(int p,int l,int r,int mod){
    if(l<=t[p].l && r>=t[p].r) return t[p].sum%mod;//如果被覆盖,就返回维护的值
    spread(p,mod);//下传懒标记,并查询左右儿子
    int mid=t[p].l+t[p].r>>1;
    ll ans=0;
    if(l<=mid) ans=(ans+ask(p*2,l,r,mod))%mod;
    if(r>mid) ans=(ans+ask(p*2+1,l,r,mod))%mod;//累加答案,返回左右儿子的和
    return ans%mod;
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int n,m;cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>arr[i];
    build(1,1,n,mod);
    for(int i=1;i<=m;i++){
        int l,r,x;cin>>l>>r>>x;
        int mu=ksm(r-l+1,mod-2);
        int tem=x*mu%mod;
        int tem2=(1-mu+mod)%mod;
        change2(1,l,r,tem2,mod);
        change(1,l,r,tem,mod);
    }
    for(int i=1;i<=n;i++)
        cout<<ask(1,i,i,mod)<<" ";
    //system("pause");
    return 0;
}
AtCoder比赛类型深度对比:ABC/ARC/AGC到底该打哪个? 本文深度解析AtCoder三大赛事ABC、ARC和AGC的核心差异与定位。ABC是新手友好、每周举行的入门赛,题目难度平滑,适合0-1999Rating选手练习速度与基础算法。ARC为中坚选手的试炼场,侧重算法深度与思维挑战,是冲击更高Rating的关键。AGC则为顶尖高手的月度旗舰赛,注重原创性与极限思维。文章结合赛制、难度数据和评分策略,为不同水平选手提供了清晰的参赛选择与进阶路径建议。 阅读详情

相关推荐

AtCoder初学者比赛:编程学习

ABC比赛为初学者提供了一个良好的平台,让他们在编程竞赛中获得实践经验,并提高他们的编程技能。在编程领域,AtCoder Beginner Contest(ABC)是一个非常受欢迎的比赛,旨在帮助初学者提高他们的编程能力。在这篇文章中,我们将介绍ABC比赛的一些基本概念,并提供一些示例代码来帮助您更好地理解。让我们来看一个简单的示例,来帮助您了解ABC比赛的工作原理。希望本文能帮助您了解AtCoder初学者比赛(ABC)的基本概念,并为您的编程学习之旅提供一些指导。给定两个整数A和B,计算它们的和。

IELLQUI8的博客 2864

ABC332 A-F

题解

Muelsyse_的博客 415

立创EDA手动拼板实战:当自带功能不够用,如何用‘复制粘贴’搞定异形拼版与特殊布局

本文详细介绍了立创EDA手动拼板技术在异形拼版与特殊布局中的应用实战。通过CTRL+SHIFT+V等核心操作技巧,解决混合尺寸拼板、特殊间距需求等复杂场景,提升PCB设计效率与灵活性,特别适合需要高精度控制的射频电路和医疗设备项目。

weixin_31967485的博客 386

【abc】332 D - Swapping Puzzle (交换i和i+1行或者i和i+1列使得a矩阵和b矩阵相同,用next_permutation函数和逆序对)

【abc】332 D - Swapping Puzzle (交换i和i+1行或者i和i+1列使得a矩阵和b矩阵相同,用next_permutation函数和逆序对)

m0_73896521的博客 1107

云漾AI创作平台实战:如何用GPT4.0+Midjourney快速生成商业级插画(附Prompt模板)

本文详细介绍了如何利用云漾AI创作平台结合GPT4.0和Midjourney快速生成商业级插画。通过智能文案生成与视觉化工作流,大幅提升创作效率,适用于电商、社交媒体等多种场景。文章包含实用Prompt模板和参数调整技巧,帮助设计师和内容创作者高效产出专业插画。

weixin_29251567的博客 217

RAG项目简历包装指南:从“流水线工人”到“问题解决者”的跃迁(附代码与思路)

本文代码已在Python 3.11 + CUDA 12.3环境测试,部分功能需LangChain 0.2+支持。

Conan_0728的博客 1885

AtCoder Beginner Contest 332

AtCoder Beginner Contest 332

青少年趣味编程 1138

2025年09月中国电子学会青少年软件编程(Python)等级考试试卷(一级)答案 + 解析

2025年09月中国电子学会青少年软件编程(Python)等级考试试卷(一级)答案 + 解析

伶俐角少儿编程 639

AtCoder Beginner Contest 389

AtCoder Beginner Contest 389

青少年趣味编程 938

YOLO系列算法改进 | C2PSA改进篇 | 融合BinaryAttention二值化注意力 | 轻量化与效率双提升,适用于高分辨率图像检测与边缘部署场景 | CVPR 2026

YOLO系列算法改进 | C2PSA改进篇 | 融合BinaryAttention二值化注意力 | 轻量化与效率双提升,适用于高分辨率图像检测与边缘部署场景 | CVPR 2026 (以YOLO26最新目标检测模型为基础,利用C2PSA_BinaryAttention创新模块进行改进)

2502_91881744的博客 163

操作系统实验四 进程运行轨迹的跟踪与统计(哈工大李治军)

实验4 进程运行轨迹的跟踪与统计 实验目的 掌握 Linux 下的多进程编程技术; 通过对进程运行轨迹的跟踪来形象化进程的概念; 在进程运行轨迹跟踪的基础上进行相应的数据统计,从而能对进程调度算法进行实际的量化评价,更进一步加深对调度和调度算法的理解,获得能在实际操作系统上对调度算法进行实验数据对比的直接经验。 实验内容 进程从创建(Linux 下调用 fork())到结束的整个过程就是进程的生命期,进程在其生命期中的运行轨迹实际上就表现为进程状态的多次切换,如进程创建以后会成为就绪态;当该进程被调度以

leoabcd12的博客 4652

AtCoder Beginner Contest 332 A-E 题解

AtCoder Beginner Contest 332 A-E 题解

超哥聊信奥 1660

可食用野生植物检测实战:基于YOLOv11的智能识别系统全流程指南

本文介绍了一种基于YOLOv11的可食用野生植物智能识别系统。该系统通过深度学习技术,能在0.2秒内精准识别植物是否可食用,准确率高达92%。文章详细阐述了从数据采集、标注到模型训练、验证的全流程,并开发了用户友好的Tkinter交互界面。该系统解决了户外探险和植物研究中植物识别的痛点,具有高精度、实时性和强泛化能力的特点,为户外安全提供了智能化解决方案。

FJN110的博客 164

AtCoder Beginner Contest 325

AtCoder Beginner Contest 325

青少年趣味编程 1095

GD32F130之USART多机通信

简介 在多机通信中,一个从机应该只接收它需要接收的数据,且只应该在它需要接收数据时才检测串口。而始终接收RX线上的数据对从机来说是一种负担。 多机通信硬件设计 远距离方案:RS485 板级方案: 静默模式 静默模式有什么作用? 答:如果 USART 处于静默模式,所有的接收状态标志位将不会被置位。 如何进入静默模式? 答:软件可以通过将 USART_CMD 寄存器中MMCMD 位置 1 使 USART 进入静默模式。 如何从静默模式中唤醒? 答:有两种方式可选,①检测到总线

luliplus的博客 299

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

AtCoder Beginner Contest 376

AtCoder Beginner Contest 376

青少年趣味编程 857

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

AtCoder Beginner Contest 363

AtCoder Beginner Contest 363

青少年趣味编程 835

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

AtCoder Beginner Contest 322

AtCoder Beginner Contest 322

青少年趣味编程 738

AtCoder Beginner Contest 393

AtCoder Beginner Contest 393

青少年趣味编程 987

AtCoder Beginner Contest 329

AtCoder Beginner Contest 329

青少年趣味编程 973

AtCoder Beginner Contest 387

AtCoder Beginner Contest 387

青少年趣味编程 841

AtCoder Beginner Contest 306

AtCoder Beginner Contest 306

青少年趣味编程 1012

AtCoder Beginner Contest 388

AtCoder Beginner Contest 388

青少年趣味编程 769

AtCoder Beginner Contest 396

AtCoder Beginner Contest 396

青少年趣味编程 630

AtCoder Beginner Contest 304

AtCoder Beginner Contest 304

青少年趣味编程 719

AtCoder Beginner Contest 386

AtCoder Beginner Contest 386

青少年趣味编程 848
上一篇: 蓝桥算法小白双周赛第一场题解2023.12.9
下一篇: AtCoder ABC335 E - Non-Decreasing Colorful Path(拓扑排序、并查集)
华年似锦
博客等级 码龄4年 362粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值