2025蓝桥杯C++ A组省赛 题解
昨天打完蓝桥杯本来想写个 p y t h o n python python A A A 组的题解,结果被队友截胡了。今天上课把 C + + A C++A C++A 组的题看了,感觉挺简单的,所以来水一篇题解。
这场 B B B 是一个爆搜, C C C 利用取余的性质比较好写, D D D 是个猜猜题,当然如果模拟也是可以的, E G EG EG 是数学, F H FH FH 需要预处理。 H H H 是基环树,需要拓扑排序+单调队列维护区间最大值。
p y t h o n python python 和 c + + c++ c++ 相比,我觉得 c + + c++ c++ 组的题要更简单(可能也有我 p y t h o n python python 不太熟悉的原因)。 p y t h o n python python 组全是暴力,我还暴力苦手,最后三题分别是爆搜剪枝,单调栈优化+并查集,反悔贪心。 c + + c++ c++ 组只有 B B B 是暴力,大部分是偏思维和算法,打多了 a c m acm acm 当然会觉得简单一些。
因为没有 O J OJ OJ,所以我也不能保证思路和代码一定正确,仅当作参考,欢迎斧正。
2025蓝桥杯python A组题解
注:A-H在洛谷测试全部通过,但是洛谷民间数据较弱,不排除会有bug
A 寻找质数
题面:
第 2025 2025 2025 个质数是多少?
思路:
直接从小到大暴力枚举每一个数,判断是否是素数,到第 2025 2025 2025 个停止就可以了。
n n n 个数里大概有 n ln n \dfrac{n}{\ln n} lnnn 个数是素数, ln n \ln n lnn 大概也就是十几,所以不需要担心越界问题。
code:
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;vector<int> primes;
bool check(int n){if(n==1)return false;for(int i=2;i*i<=n;i++)if(n%i==0)return false;return true;
}int main(){for(int i=2;primes.size()<2025;i++)if(check(i))primes.push_back(i);cout<<primes.back();return 0;
}
B 黑白棋
题面:
给你一个 6 × 6 6\times 6 6×6 的棋盘,有的位置一开始就填有棋子,其余格子需要你进行填充,要求:
- 每一行,每一列均只有三个白棋,三个黑棋
- 在某一行或某一列中,不能出现三个同色棋子连续的情况
- 每一行棋子排列方式唯一,与其他行各不相同。同理每一列。行列之间不受限制。
题目保证有唯一解。按照以下格式输出答案:
黑色棋子用 1 1 1 表示,白色棋子用 0 0 0 表示。
从左到右、从上到下的顺序,依次遍历棋盘上的所有格子,并将这些值拼接成一个长度为 36 36 36 的字符串。
思路1:
暴力枚举所有状态,然后判断状态是否成立。
枚举除了已经确定的位置以外的位置的落子情况(总共有 26 26 26 个位置),每个位置只有两种情况(放白棋或者放黑棋),所以总的可能数是 2 26 ≈ 6 × 1 0 8 2^{26}\approx 6\times 10^8 226≈6×108。
枚举到一种状态后,将已经确定的位置的状态加入枚举的状态中。然后判断状态是否成立即可。
总的时间复杂度大概是 总可能数 × \times × (加入已经确定的位置的状态 + + + 判断),后面这个东西的时间复杂度是一个大常数,预估大概也就是 100 100 100。所以能跑动,就是慢一点。
code:
跑了 139 139 139 秒
#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
using namespace std;
typedef long long ll;void print(string s){for(int i=0;i<6;i++,puts(""))for(int j=0;j<6;j++)cout<<s[i*6+j]<<" ";
}string b2s(ll n){//二进制转string string s;for(ll i=0;i<36;i++)s+="01"[(n>>i)&1];return s;
}
int s2b(string s){//string转二进制ll n=0;for(auto x:s)n=(n<<1)+(x-'0');return n;
}
int idx[]={0,1,3,9,16,17,26,29,31,34};
int colors[]={1,0,0,0,0,0,1,1,0,1};//1,1,1,1,1,1,1,1,1,1
string treat(string s){s=s.substr(0,26);//因为在加入10个固定位置的状态前只有26位 for(int i=0;i<10;i++){int id=idx[i];int c=colors[i];//向id上插入cs=s.substr(0,id)+(c?"1":"0")+s.substr(id);}return s;
}bool check(string s){for(int i=0;i<6;i++){int t=0;for(int j=0;j<6;j++)if(s[i*6+j]=='0')t++;if(t!=3)return false;}for(int j=0;j<6;j++){int t=0;for(int i=0;i<6;i++)if(s[i*6+j]=='0')t++;if(t!=3)return false;}for(int i=0;i<6;i++)for(int j=0;j+2<6;j++)if(s[i*6+j]==s[i*6+j+1] && s[i*6+j+1]==s[i*6+j+2])return false;for(int j=0;j<6;j++)for(int i=0;i+2<6;i++)if(s[i*6+j]==s[(i+1)*6+j] && s[(i+1)*6+j]==s[(i+2)*6+j])return false;set<string> S;for(int i=0;i<6;i++){string t;for(int j=0;j<6;j++)t+=s[i*6+j];S.insert(t);}if(S.size()!=6)return false;S.clear();for(int j=0;j<6;j++){string t;for(int i=0;i<6;i++)t+=s[i*6+j];S.insert(t);}if(S.size()!=6)return false;return true;
}int main(){for(ll i=0;i<(1<<26);i++){string t=treat(b2s(i));if(check(t)){//print(t);cout<<t;//101001010011101100010110011001100110break;}}return 0;
}
/*
1 0 1 0 0 1
0 1 0 0 1 1
1 0 1 1 0 0
0 1 0 1 1 0
0 1 1 0 0 1
1 0 0 1 1 0*/
思路2:
爆搜剪枝
按顺序枚举每个点,尝试落子。然后加点剪枝。
这样搜的好处是可以剪枝,不像思路1需要枚举到所有的状态,因为这个题的要求条件非常苛刻,所以可以狠狠剪枝,所以速度要快很多。
思路3:
直接手玩
首先很容易发现 ( 1 , 3 ) (1,3) (1,3) ( 3 , 4 ) (3,4) (3,4) 只能放黑棋,否则会导致三个白棋行/列连续。
接下来假设 ( 4 , 4 ) (4,4) (4,4) 放白棋,那么可以推出以下局面:
- 因为第四列已经有三白棋,因此 ( 5 , 4 ) (5,4) (5,4) ( 6 , 4 ) (6,4) (6,4) 均为黑棋
- 因为第五行已经有三黑棋,因此 ( 5 , 1 ) (5,1) (5,1) ( 5 , 2 ) (5,2) (5,2) ( 5 , 5 ) (5,5) (5,5) 均为白棋
- 因为第二列已经有三白棋,因此 ( 2 , 2 ) (2,2) (2,2) ( 3 , 2 ) (3,2) (3,2) ( 4 , 2 ) (4,2) (4,2) 均为黑棋
- 连续三黑棋,矛盾
因此 ( 4 , 4 ) (4,4) (4,4) 放黑棋,从而 ( 5 , 4 ) (5,4) (5,4) 放白棋, ( 6 , 4 ) (6,4) (6,4) 放黑棋。
因为第六行连续两个黑棋了, ( 6 , 3 ) (6,3) (6,3) 和 ( 6 , 6 ) (6,6) (6,6) 只能放白棋,因此 ( 6 , 1 ) (6,1) (6,1) 放黑棋。
发现 ( 5 , 2 ) (5,2) (5,2) 如果放白棋,那么 ( 2 , 2 ) (2,2) (2,2) ( 3 , 2 ) (3,2) (3,2) ( 4 , 2 ) (4,2) (4,2) 放黑棋矛盾。因此 ( 5 , 2 ) (5,2) (5,2) 只能放黑棋,同理 ( 2 , 2 ) (2,2) (2,2) 只能放黑棋。可以继续推出:
- ( 5 , 1 ) (5,1) (5,1) ( 5 , 5 ) (5,5) (5,5) 放白棋
- ( 4 , 5 ) (4,5) (4,5) 放黑棋
- ( 4 , 3 ) (4,3) (4,3) ( 4 , 6 ) (4,6) (4,6) 放白棋
继续推出:
- ( 1 , 6 ) (1,6) (1,6) ( 2 , 6 ) (2,6) (2,6) 放黑棋
- ( 1 , 5 ) (1,5) (1,5) 放白棋
- ( 2 , 5 ) (2,5) (2,5) 放黑棋
- ( 2 , 1 ) (2,1) (2,1) ( 2 , 3 ) (2,3) (2,3) 放白棋
- ( 3 , 3 ) (3,3) (3,3) 放黑棋
- ( 3 , 2 ) (3,2) (3,2) 放白棋,从而 ( 3 , 1 ) (3,1) (3,1) 放黑棋
- ( 4 , 1 ) (4,1) (4,1) 放白棋,从而 ( 4 , 2 ) (4,2) (4,2) 放黑棋
C 抽奖
题意:
抽奖机有三个转轮,每个转轮上有 n n n 个数字图案,标号为 1 ∼ n 1 \sim n 1∼n ,按照从 1 ∼ n 1\sim n 1∼n 顺序转动,当转到第 n n n 个图案时会从第一个继续开始。奖项如下:
- 三个相同的图案,积分 + 200 +200 +200
- 两个相同的图案,积分 + 100 +100 +100
- 三个数字图案,从左到右连续(例如 123 123 123 ),积分 + 200 +200 +200
- 三个数字图案,经过排序后连续,(例如 213 , 321 213, 321 213,321),积分 + 100 +100 +100
抽奖机处于初始状态,三个转轮都处于第一个位置。每次开始抽奖,都会产生三个对应的随机数 x i 1 , x i 2 , x i 3 x_{i1}, x_{i2}, x_{i3} xi1,xi2,xi3 ,表示第 j j j 个转轮会向后转动 x i j x_{i j} xij 次停下。下次抽奖时,转轮会从上一次转动后的位置开始继续转动。
注意,一次抽奖最多只能获得一次积分,如果同时命中多个奖项,以积分最大的那个奖项为准。
请问,如果执行 m m m 次抽奖,总积分值是多少?
n , m ≤ 1 0 3 n,m\le 10^3 n,m≤103, a i , b i , c i ≤ 9 a_i,b_i,c_i\le 9 ai,bi,ci≤9, x i j ≤ 1000 x_{ij}\le 1000 xij≤1000
思路:
把循环和取余联系起来,而不是一个一个数,就会好写很多。
code:
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=1e3+5;int n,m;
int a[3][maxn];
int p[3];int main(){cin>>n;for(int i=0;i<3;i++)for(int j=0;j<n;j++)cin>>a[i][j];cin>>m;int ans=0;for(int i=1,t;i<=m;i++){for(int i=0;i<3;i++){cin>>t;p[i]=(p[i]+t)%n;}int x[]={a[0][p[0]],a[1][p[1]],a[2][p[2]]};if(x[0]==x[1] && x[1]==x[2])ans+=200;else if(x[0]+1==x[1] && x[1]+1==x[2])ans+=200;else {if(x[0]>x[1])swap(x[0],x[1]);if(x[1]>x[2])swap(x[1],x[2]);if(x[0]>x[1])swap(x[0],x[1]);if(x[0]==x[1] || x[1]==x[2])ans+=100;if(x[0]+1==x[1] && x[1]+1==x[2])ans+=100;}}cout<<ans<<endl;return 0;
}
/*
4
3 2 4 1
2 2 2 2
4 3 0 9
3
4 4 4
3 1 1
40 39 2*/
D 红黑树
题意:
小蓝最近学习了红黑树,红黑树是一种特殊的二叉树,树上的结点有两种类型:红色结点和黑色结点。
小蓝在脑海中构造出一棵红黑树,构造方式如下:
- 根结点是一个红色结点
- 如果当前结点 c u r N o d e curNode curNode 是红色结点,那么左子结点 c u r N o d e . l e f t curNode.left curNode.left 是红色结点,右子结点 c u r N o d e . r i g h t curNode.right curNode.right 是黑色结点
- 如果当前结点 c u r N o d e curNode curNode 是黑色结点,那么左子结点 c u r N o d e . l e f t curNode.left curNode.left 是黑色结点,右子结点 c u r N o d e . r i g h t curNode.right curNode.right 是红色结点
输入格式:
输入的第一行包含一个正整数 m m m ,表示小蓝挑选的结点数。
接下来 m m m 行,每行包含两个正整数 n i k i n_i\ k_i ni ki ,用一个空格分隔,表示小蓝挑选的结点是第 n i n_i ni 行(从上往下数)第 k i k_i ki 个(从左往右数)结点。
输出格式:
输出 m m m 行,每行包含一个字符串,依次表示小蓝每次挑选的结点的答案。RED
表示红色结点,BLACK
表示黑色结点。
数据范围:
m ≤ 10 m\le 10 m≤10, n i ≤ 30 n_i\le 30 ni≤30, k i ≤ 2 n i − 1 k_i\le 2^{n_i-1} ki≤2ni−1
思路:
其实仔细想想也不算神秘猜猜题。毕竟这是正了八经的完全二叉树的性质。
对一个完全二叉树,从上到下,从左到右进行编号,会有一个性质:对一个节点,编号为 i i i,那么它的左孩子节点编号为 2 i 2i 2i,右孩子节点的编号为 2 i + 1 2i+1 2i+1。
观察一下,你很容易看出来对一个节点,它的左孩子是保持它的颜色,它的右孩子是翻转它的颜色。如果把编号看成二进制数,左孩子编号相当于在它的编号后面加一个 0 0 0,右孩子编号相当于在它的编号后面加一个 1 1 1。这说明了什么?这说明节点颜色和它编号二进制的 1 1 1 的个数有关。
所以你只需要算出第 n n n 行第 k k k 个节点的编号,然后数一下它的二进制中 1 1 1 的个数即可。
再观察一下可以发现第 n n n 行的点只是二进制位上第 n − 1 n-1 n−1 位(从第零位开始算)为 1 1 1,除去最高位 1 1 1,剩余的二进制位组成的数就是 k − 1 k-1 k−1。
code:
#include <iostream>
#include <cstdio>
using namespace std;int count(int x){int cnt=0;while(x){if(x&1)cnt++;x>>=1;}return cnt;
}int n;int main(){cin>>n;for(int i=1,_,k;i<=n;i++){cin>>_>>k;
// cout<<k<<" "<<count(k-1)<<endl;cout<<((count(k-1)%2)?"BLACK":"RED")<<endl;}return 0;
}
/*
2
1 1
2 2*/
E 黑客
题意:
小蓝正在两台电脑之间拷贝数据,数据是一个 n × m n\times m n×m 大小的正整数矩阵,因此总共有 n × m + 2 n\times m+2 n×m+2 个由空格分开的整数,其中前两个整数分别为 n n n 和 m m m。然而,有黑客入侵了小蓝的电脑,导致这 n × m + 2 n\times m+2 n×m+2 个正整数的顺序被打乱了,小蓝想知道最多可能有多少个不同的原矩阵。
两个矩阵相同当且仅当它们行数相同、列数分别相同,且每个位置上的数相同。
输入格式:
输入的第一行包含一个正整数 n × m + 2 n\times m+2 n×m+2 。
第二行包含 n × m + 2 n\times m+2 n×m+2 个正整数 a 1 , a 2 … a n × m + 2 a_1,a_2\dots a_{n\times m+2} a1,a2…an×m+2 ,相邻整数之间使用一个空格分隔。
输出格式:
输出一行包含一个整数表示答案。答案可能很大,请输出答案除以 1000000007
的余数。
数据范围:
n × m + 2 ≤ 5 × 1 0 5 n\times m +2\le 5\times 10^5 n×m+2≤5×105, a i ≤ 5 × 1 0 5 a_i\le 5\times 10^5 ai≤5×105
思路:
首先需要取出两个数作为 n , m n,m n,m。其次这个两个数肯定是 n × m n\times m n×m 的因数(废话)。所以我们可以 O ( n ) O(\sqrt n) O(n) 枚举总数的因数,(如果存在这两个数)去除这两个数,并计算剩余 n × m n\times m n×m 个数的答案。
因为矩阵相同只需要对应位置上的数相同,这个数原本的位置不重要,所以我们可以把所有数按照值统计起来。
如果原本的数各不相同,那么显然总的可能数就是 n m nm nm 个数的全排列,即 A n m n m = ( n m ) ! A_{nm}^{nm}=(nm)! Anmnm=(nm)!。如果其中有 k k k 个数是相等的,我们就需要消除它们之间全排对整体全排列的影响。也就是除序原理。它们 k k k 个数全排列有 k ! k! k! 种可能,这意味着在整体的全排列中会有 k ! k! k! 个其实是一种排列(因为整体在全排时把它们看作是不同的元素),所以需要在原本的基础上除以 k ! k! k!。以此类推,对多个不同的个数大于 1 1 1 的数也都是这样。
假设值为 i i i 的数有 c n t i cnt_i cnti 个,那么答案就是: ( n m ) ! ∏ i c n t i ! \dfrac{(nm)!}{\prod_icnt_i!} ∏icnti!(nm)!
所以再预处理一下阶乘和阶乘倒数即可。
因为 n , m n,m n,m 和 m , n m,n m,n 算两种情况,所以在枚举因数的时候,如果因数 p p p 和 n m / p nm/p nm/p 不一致,答案需要计两遍。
算阶乘可以用 n ! = ( n − 1 ) ! ∗ n n! = (n-1)!*n n!=(n−1)!∗n 递推,算阶乘倒数可以用 1 ( n − 1 ) ! = 1 n ! ∗ n \dfrac{1}{(n-1)!}=\dfrac{1}{n!}*n (n−1)!1=n!1∗n 倒推。
code:
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=5e5+5;
const int N=5e5;
typedef long long ll;
const ll mod=1e9+7;ll qpow(ll a,ll b){//a^b (%mod)ll ans=1,base=a;while(b){if(b&1)ans=ans*base%mod;base=base*base%mod;b>>=1;}return ans;
}
ll inv(ll x){return qpow(x,mod-2);
}ll nm;
ll cnt[maxn];
ll fac[maxn],ifac[maxn];int main(){fac[0]=1;for(int i=1;i<=N;i++)fac[i]=fac[i-1]*i%mod;ifac[N]=inv(fac[N]);for(int i=N;i>=1;i--)ifac[i-1]=ifac[i]*i%mod;ll ans=0;cin>>nm;for(int i=1,t;i<=nm;i++){cin>>t;cnt[t]++;}nm-=2;for(ll i=1;i*i<=nm;i++){if(nm%i!=0)continue;cnt[i]--;cnt[nm/i]--;if(cnt[i]>=0 && cnt[nm/i]>=0){
// cout<<i<<" "<<nm/i<<endl; ll t=fac[nm];for(int j=1;j<=N;j++)t=t*ifac[cnt[j]]%mod;
// cout<<t<<endl;ans+=t;if(i*i!=nm)ans+=t;ans%=mod;}cnt[i]++;cnt[nm/i]++;}cout<<ans;return 0;
}
/*
6
2 2 1 4 3 3*/
F 好串的数目
题意:
对于一个长度为n 的字符串 s = s 0 s 1 … s n − 1 s=s_0s_1\dots s_{n-1} s=s0s1…sn−1 来说,子串的定义是从中选出
两个下标 l , r l,r l,r ( 0 ≤ l ≤ r ≤ n − 1 0\le l\le r\le n-1 0≤l≤r≤n−1),这之间所有的字符组合起来的一个新的字符串:
s ’ = s l s l + 1 … s r s’ = s_ls_{l+1} \dots s_r s’=slsl+1…sr 就是其中一个子串。
现在给出一个只有数字字符 0 ∼ 9 0\sim9 0∼9 组成的数字字符串,小蓝想要知道在其
所有的子串中,有多少个子串是好串。一个子串是好串,当且仅当它满足以下
两个条件之一:
- 单字符子串一定是好串,即当子串长度为 1 1 1 时,它总是好串;
- 长度大于 1 1 1 时,可以拆分为两个连续非递减子串。
其中,一个串 p = p 0 p 1 … p k − 1 p = p_0p_1\dots p_{k-1} p=p0p1…pk−1 为连续非递减子串是指,对于所有 1 ≤ i < k 1 \le i < k 1≤i<k,满足 p i = p i − 1 p_i=p_{i-1} pi=pi−1 或 p i = p i + 1 + 1 p_i = p_{i+1} + 1 pi=pi+1+1 。即数字串中的每一个数字,要么等于上一个数字,要么等于上一个数字加 1 1 1 。例如 12233 、 456 12233 、456 12233、456 是连续非递减子串。
输入格式:
输入一行包含一个字符串 s s s
输出格式:
输出一行包含一个整数表示答案,即好串的数目。
数据范围:
1 ≤ n ≤ 1 0 5 1\le n\le 10^5 1≤n≤105, s s s 中只包含数字字符 0 ∼ 9 0\sim 9 0∼9
思路:
如果我们把整个串划分成若干段连续非递减子串,比如 122 ‾ 5 ‾ 8 ‾ \underline{122}\underline{5}\underline{8} 12258。只要我们选取的区间不包含超过两个段,那么它就是一个好串。
我们可以枚举左端点,然后快速处理出右端点。其实也就是对一个左端点,我们需要知道左端点所在段的后一个段的右端点在哪里。我们可以预处理这个东西,于是就做完了。
code:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=1e5+5;
typedef long long ll;int n;
string s;
int mir[maxn];int main(){cin>>s;n=s.length();s=" "+s;for(int r=n,l=n+1,lst=n+1;r>=1;r=l-1){//双指针拓展段,每次循环得到一段,段为[l,r]l--;while(l-1>=1 && (s[l]-s[l-1]==1 || s[l]-s[l-1]==0))l--;for(int i=l;i<=r;i++)mir[i]=lst;
// cout<<l<<" "<<r<<" "<<lst<<endl;lst=r+1;}ll ans=0;for(int l=1,r,len;l<=n;l++){//右端点在[l,r)任取 r=mir[l];len=r-l;ans+=len;}cout<<ans;return 0;
}
/*
1225897856*/
G 地雷阵
题意:
小蓝正在平面直角坐标系中的第一象限里玩一个逃生小游戏,在第一象限中埋有 n n n 颗地雷,第 i i i 颗地雷的坐标为 ( x i , y i ) (x_i, y_i) (xi,yi) ,触发范围为以 ( x i , y i ) (x_i, y_i) (xi,yi) 为圆心,半径为 r i r_i ri 的圆。一旦小蓝走进了圆内就会触发地雷导致游戏失败。小蓝初始在原点 ( 0 , 0 ) (0, 0) (0,0) 上,他需要在第一象限内选择一个方向一直往前走,如果能不触发任何地雷即可成功通关游戏。他想知道在 [ 0 , π 2 ] [0,\dfrac{\pi}{2}] [0,2π] 中均匀随机选择一个方向,即在 0 ° 0\degree 0° (朝向 x x x 轴正方向)至 90 ° 90\degree 90°(朝向 y y y 轴正方向)之间随机选择一个方向,通关游戏的概率是多少?
输入格式:
输入的第一行包含一个正整数 n n n 。
接下来 n n n 行,每行包含三个正整数 x i , y i , r i x_i, y_i, r_i xi,yi,ri,相邻整数之间使用一个空格分隔。
输出格式:
输出一行包含一个实数,四舍五入保留三位小数,表示答案。
数据范围:
n ≤ 1 0 5 n\le 10^5 n≤105, x i , x y ≤ 1 0 4 x_i,x_y\le 10^4 xi,xy≤104, r i ≤ m i n ( x i , y i ) r_i\le min(x_i,y_i) ri≤min(xi,yi)
思路:
r i ≤ m i n ( x i , y i ) r_i\le min(x_i,y_i) ri≤min(xi,yi) 说明所有圆不会超出第一象限,可以少一些特殊情况判断。
如果在第一象限有一个圆,它的圆心坐标为 ( x , y ) (x,y) (x,y),半径为 r r r。那么可以得到下图:
不难发现在 [ 0 , π 2 ] [0,\dfrac{\pi}{2}] [0,2π] 中, [ α − θ , α + θ ] [\alpha-\theta,\alpha+\theta] [α−θ,α+θ] 这段是不能取的,而 α = arctan y x , θ = arcsin r R = arcsin r x 2 + y 2 \alpha=\arctan{\dfrac yx},\theta=\arcsin{\dfrac{r}{R}}=\arcsin{\dfrac{r}{\sqrt{x^2+y^2}}} α=arctanxy,θ=arcsinRr=arcsinx2+y2r,其中 R R R 代表从坐标原点到圆心的距离。
n n n 个圆,那么就有 n n n 段不能取的区间。我们取这些区间的并集,假设长度为 l e n len len,那么总长度为 π 2 \dfrac{\pi}{2} 2π,不通关的概率就是 l e n π 2 \dfrac{len}{\dfrac{\pi}{2}} 2πlen,通关概率就是 1 − l e n π 2 1-\dfrac{len}{\dfrac{\pi}{2}} 1−2πlen。
code:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=1e5+5;
const double pi=acos(-1);
#define pdd pair<double,double> int n;
vector<pdd> range;int main(){cin>>n;for(int i=1;i<=n;i++){double x,y,r;cin>>x>>y>>r;double alpha=atan(y/x);double theta=asin(r/sqrt(x*x+y*y));range.push_back(pdd(alpha-theta,alpha+theta));}sort(range.begin(),range.end());double p=0,len=0;for(auto [l,r]:range){if(r<p){continue;}else if(l<p){len+=r-p;p=r;}else {len+=r-l;p=r;}}printf("%.3f",1-len/(pi/2));return 0;
}
/*
1
2 2 12
1 3 1
3 1 1*/
H 扫地机器人
题意:
在一个含有 n n n 个点 n n n 条边的无重边无自环的连通无向图中,有一个扫地机器人在执行清扫作业,其中结点 i i i 的标记 t i ∈ { 0 , 1 } t_i \in \{0,1\} ti∈{0,1} 如果为 1 1 1 ,则说明该结点需要进行清扫,扫地机器人在到达这个结点时会顺便进行清扫工作。机器人想知道,如果选定任意结点出发,每条边只能经过一次的话,最多能清扫多少个待清扫结点?
输入格式:
输入的第一行包含一个正整数 n n n 。
第二行包含 n n n 个整数 t 1 , t 2 , … , t n t_1,t_2,\dots,t_n t1,t2,…,tn,相邻整数之间使用一个空格分隔。
接下来 n n n 行,每行包含两个正整数 u i , v i u_i, v_i ui,vi ,用一个空格分隔,表示结点 u i u_i ui 和结点 v i v_i vi 之间有一条边。
输出格式:
输出一行包含一个整数表示答案。
数据范围:
n ≤ 5 × 1 0 5 n\le 5\times 10^5 n≤5×105, t i ∈ { 0 , 1 } t_i \in \{0,1\} ti∈{0,1}, 1 ≤ u i , v i ≤ n 1\le u_i,v_i\le n 1≤ui,vi≤n
思路:
终于是通过洛谷的数据了,这题阴的很,出题人坏的很。重构一遍发现该错的地方还是错,不是写法有问题,而是情况没讨论全。
n n n 个点 n n n 条边,还无重边无自环,连通图。这就是一个基环树。
基环树说白了就是在一棵树的基础上加一条边,于是变成了一种图。它存在唯一的环,环上的每个点都可以作为树根向外衍生出一棵树。因为无重边无自环,所以环长最小为 3 3 3。
比如这个题的样例对应的图(带圈的表示待清扫结点):
我们的答案路径有三种情况,这就是这个题阴的地方,我们需要对每种情况进行计数,并取最大值。三种情况分别为:
- 在以环上某点为根的一颗树内。比如上图的 8 → 2 → 9 8\rightarrow 2\rightarrow 9 8→2→9
- 从某棵树的树叶开始,走到树根(树根在环上),然后走到另一个树根,再走到这棵树的树叶。比如这个样例的答案路径就是 3 → 1 → 4 → 6 → 7 3\rightarrow 1\rightarrow 4\rightarrow 6\rightarrow 7 3→1→4→6→7。
- 环上某点有两个以上的儿子,以其中一个儿子所在子树开始,走到环上该点,绕环转一圈回到该点,再进入另一个儿子所在子树。
因为题目只要求边只能走一遍,但是没说点不能走多遍。阴不阴?
情况一和情况三都比较好处理,主要看你的实现方式。假设我们把待清理点叫做 1 1 1 点。
- 如果你用拓扑排序找环:那么找环的过程中,相当于对每棵树从叶向上遍历,那么遍历过程中顺便把某点的两个最大子树的 1 1 1 点个数加起来,就得到了情况一的答案。然后枚举环上各点,将它的两个最大子树和环上的 1 1 1 点个数加起来就是情况三的答案
- 如果你用 d f s dfs dfs 找环(这题明确就一个环,也不需要找连通分量,所以没必要上 t a r j a n tarjan tarjan,一个 d f s dfs dfs 就解决了):找到环后,以每个点为根,单独进行 d f s dfs dfs,直接去算情况一和情况三的答案。
对于情况二,如果用拓扑排序,我们可以处理出以环上某点作为起点,向环外走可达的最大 1 1 1 点个数。于是我们就可以用拓扑排序来删点,边删边算上面说的东西。最后剩一下一个环。
我们可以把这个环展开,展开后有 t n tn tn 个点,按顺序重新编号,假设 a i a_i ai 表示第 i i i 个点是或不是 1 1 1 点, b i b_i bi 表示第 i i i 个点向环外走可达的最大 1 1 1 点个数(也就是上面提到的那个东西),从某个点到另外一个点的答案就是 b i + a i + 1 + a i + 2 + ⋯ + a j − 1 + b j b_i+a_{i+1}+a_{i+2}+\dots+a_{j-1}+b_j bi+ai+1+ai+2+⋯+aj−1+bj。
我们要算答案,就是要枚举左端点 i i i,然后枚举右端点 j j j,计算上面的式子,并取最大值。但是如果我们走环的另一个方向呢?比如样例中的环从 1 → 4 1\rightarrow 4 1→4 也可以是 1 → 5 → 4 1\rightarrow 5\rightarrow 4 1→5→4。其实也好解决,我们将 a , b a,b a,b 数组再循环复制一遍放到后面,这样 i → j i\rightarrow j i→j 的另一个方向就转化为了 j → i + t n j\rightarrow i+tn j→i+tn,这是处理环时的常用策略,不理解可以看下面的图。
不过要注意,当我们枚举 i i i 的时候, j j j 的取值范围是 [ i + 1 , i + t n − 1 ] [i+1,i+tn-1] [i+1,i+tn−1]。否则区间长度大于 t n tn tn 就相当于重复了。
n ≤ 5 × 1 0 5 n\le 5\times 10^5 n≤5×105,怎么快速算呢。稍微处理一下上面的式子: b i + a i + 1 + a i + 2 + ⋯ + a j − 1 + b j = a 1 + ⋯ + a j − 1 + b j − ( a 1 + ⋯ + a i ) + b i \begin{aligned} &b_i+a_{i+1}+a_{i+2}+\dots+a_{j-1}+b_j\\ =&a_1+\dots+a_{j-1}+b_j-(a_1+\dots+a_i)+b_i \end{aligned} =bi+ai+1+ai+2+⋯+aj−1+bja1+⋯+aj−1+bj−(a1+⋯+ai)+bi如果我们枚举左端点 i i i,那么对一个 i i i,其中的 b i b_i bi 和 a 1 + ⋯ + a i a_1+\dots+a_i a1+⋯+ai 就是固定的,我们需要快速确定 j j j,使得上式最大。
我们可以预处理 a a a 的前缀和 s i = a 1 + a 2 + ⋯ + a i s_i=a_1+a_2+\dots+a_i si=a1+a2+⋯+ai。上式转化为 s j − 1 + b j − s i + b i s_{j-1}+b_j-s_i+b_i sj−1+bj−si+bi,其实我们只需要知道 [ i + 1 , i + t n − 1 ] [i+1,i+tn-1] [i+1,i+tn−1] 中 s j − 1 + b j s_{j-1}+b_j sj−1+bj 最大值即可。
可以用单调队列动态维护区间最大值。就是滑动窗口问题。或者可以用 s e t set set,时间慢一点,但是不影响。
code1:
拓扑排序
#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#include <queue>
using namespace std;
const int maxn=5e5+5;
#define pii pair<int,int>
const int inf=1e9;int n,ans=0;
set<int> g[maxn];
int clean[maxn];vector<int> ring;
set<int> S;
int to[maxn],twin[maxn];//向环外走可以走到多少1点 以它为中转点向外走两条叉的1点数
void topu(){//拓扑排序找环,并找到环上点向环外可以走到多少1点 queue<int> q;for(int u=1;u<=n;u++)if(g[u].size()==1)q.push(u);while(!q.empty()){int u=q.front();q.pop();for(auto v:g[u]){g[v].erase(u);twin[v]=max(twin[v],to[v]+to[u]);ans=max(ans,twin[v]);to[v]=max(to[v],clean[v]+to[u]);if(g[v].size()==1)q.push(v);}g[u].clear();}// for(int u=1;u<=n;u++){
// cout<<u<<":";
// for(auto v:g[u])
// cout<<v<<" ";
// cout<<endl;
// }for(int u=1;u<=n;u++)if(g[u].size()>0)S.insert(u);for(int u=*S.begin(),fa=*g[u].begin();;){ring.push_back(u);for(auto v:g[u]){if(v==fa)continue;if(v==ring[0])return;fa=u;u=v;break;}}
}int main(){cin>>n;for(int i=1;i<=n;i++)cin>>clean[i],to[i]=clean[i];for(int i=1,u,v;i<=n;i++){cin>>u>>v;g[u].insert(v);g[v].insert(u);}topu();int tn=ring.size();vector<int> a(tn*2+5),b(tn*2+5),s(tn*2+5);for(int i=1;i<=tn;i++){a[i]=a[i+tn]=clean[ring[i-1]];b[i]=b[i+tn]=to[ring[i-1]];}for(int i=1;i<=tn*2;i++)s[i]=s[i-1]+a[i];deque<pii> dq;//下标 值 for(int j=1;j<tn;j++){int val=s[j-1]+b[j];while(!dq.empty() && dq.back().second<=val)dq.pop_back();dq.push_back(pii(j,val));}for(int i=1,j=tn,val;i<=tn;i++,j++){//i为左端点,j为右端点 while(!dq.empty() && dq.front().first<=i)dq.pop_front();val=s[j-1]+b[j];while(!dq.empty() && dq.back().second<=val)dq.pop_back();dq.push_back(pii(j,val));int max_val=dq.front().second-s[i]+b[i];ans=max(ans,max_val);}for(auto u:ring){ans=max(ans,twin[u]+s[tn]-clean[u]);}cout<<ans<<endl;return 0;
}
/*
9
1 0 1 0 0 1 1 0 1
2 8
2 9
2 5
1 5
1 3
1 4
4 5
4 6
6 7*/
code2:
d f s dfs dfs
#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#include <queue>
#include <algorithm>
#include <ctime>
using namespace std;
const int maxn=5e5+5;
const int inf=1e9;
#define pii pair<int,int>
//#define int long longint n,ans=0;
set<int> g[maxn];int clean[maxn];
int to[maxn];//向环外走可以走到多少1点 vector<int> cir;
bool incir[maxn];vector<int> stk;
bool vis[maxn];
bool find_cir(int u,int fa){
// cout<<u<<' '<<fa<<endl;vis[u]=true;stk.push_back(u);for(auto v:g[u]){if(fa==v)continue;if(vis[v]){while(true){int t=stk.back();stk.pop_back();incir[t]=true;cir.push_back(t);if(t==v)break;}return true;}if(find_cir(v,u))return true;}stk.pop_back();vis[u]=false;return false;
}void dfs(int u,int fa){for(auto v:g[u]){if(incir[v] || fa==v)continue;dfs(v,u);ans=max(ans,to[v]+to[u]);to[u]=max(to[u],to[v]+clean[u]);}
}signed main(){cin>>n;for(int i=1;i<=n;i++)cin>>clean[i],to[i]=clean[i];for(int i=1,u,v;i<=n;i++){cin>>u>>v;g[u].insert(v);g[v].insert(u);}find_cir(1,-1);for(auto u:cir)dfs(u,-1);int tn=cir.size();vector<int> a(tn*2+5),b(tn*2+5),s(tn*2+5);for(int i=1;i<=tn;i++){a[i]=a[i+tn]=clean[cir[i-1]];b[i]=b[i+tn]=to[cir[i-1]];}for(int i=1;i<=tn*2;i++)s[i]=s[i-1]+a[i];set<pii> S;for(int j=1;j<tn;j++){int val=s[j-1]+b[j];S.insert(pii(val,j));}for(int i=1,j=tn,val;i<=tn;i++,j++){//i为左端点,j为右端点 val=s[j-1]+b[j];S.insert(pii(val,j));while(!S.empty() && (*S.rbegin()).second<=i)S.erase(*S.rbegin());int max_val=(*S.rbegin()).first-s[i]+b[i];ans=max(ans,max_val);}int cnt=s[tn];//环上所有1点和
// cout<<cnt<<endl;for(auto u:cir){int mx1=-inf,mx2=-inf;for(auto v:g[u]){if(incir[v])continue;if(to[v]>mx1){mx2=mx1;mx1=to[v];}else if(to[v]>mx2){mx2=to[v];}}
// cout<<"***"<<u<<" "<<mx1<<" "<<mx2<<endl;ans=max(ans,cnt+mx1+mx2);}cout<<ans<<endl;return 0;
}
/*
9
1 0 1 0 0 1 1 0 1
2 8
2 9
2 5
1 5
1 3
1 4
4 5
4 6
6 7*/
相关文章:
2025蓝桥杯C++ A组省赛 题解
昨天打完蓝桥杯本来想写个 p y t h o n python python A A A 组的题解,结果被队友截胡了。今天上课把 C A CA CA 组的题看了,感觉挺简单的,所以来水一篇题解。 这场 B B B 是一个爆搜, C C C 利用取余的性质比较好写&#…...
链接世界:计算机网络的核心与前沿
计算机网络引言 在数字化时代,计算机网络已经成为我们日常生活和工作中不可或缺的基础设施。从简单的局域网(LAN)到全球互联网,计算机网络将数以亿计的设备连接在一起,推动了信息交换、资源共享以及全球化的进程。 什…...
MySQL 常见存储引擎全解析:InnoDB、MyISAM、Memory 等对比与实战
一、什么是存储引擎? 存储引擎(Storage Engine)是 MySQL 中负责数据存储与管理的底层模块。不同的存储引擎负责处理表的读写、索引维护、事务支持、崩溃恢复等机制。 在创建表时可以指定使用的存储引擎: CREATE TABLE user (id…...
21天Python计划:零障碍学语法(更新完毕)
目录 序号标题链接day1Python下载和开发工具介绍https://blog.csdn.net/XiaoRungen/article/details/146583769?spm1001.2014.3001.5501day2数据类型、字符编码、文件处理https://blog.csdn.net/XiaoRungen/article/details/146603325?spm1011.2415.3001.5331day3基础语法与…...
Python中NumPy的统计运算
在数据分析和科学计算领域,Python凭借其丰富的库生态系统成为首选工具之一,而NumPy作为Python数值计算的核心库,凭借其高效的数组操作和强大的统计运算功能,广泛应用于机器学习、信号处理、统计分析等场景。本文将系统介绍NumPy在…...
SQL 解析 with as
sql的运行顺序 <select id"getTrendList" parameterType"java.util.HashMap" resultType"java.util.Map"><![CDATA[WITH-- 生成连续年份列表(当前年前8年到前1年)year_range AS (SELECT EXTRACT(YEAR FROM SYSD…...
07-算法打卡-链表-移除链表-leetcode(203)-第七天
1 题目地址 203. 移除链表元素 - 力扣(LeetCode)203. 移除链表元素 - 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点,并返回 新的头节点 。 示例 1:[https://assets.leetc…...
抓包神器,自研EtherCAT抓包工具
大家好,博主自研了一款以太网抓包神器,可以用于EtherCAT抓包。 把抓包工具接入以太网总线中,就能正常使用了。 上位机软件采用wireshark。 开启以下协议 抓包截图如下 时间戳的精度为5ns。...
五、adb常用命令
SDK路径下的 \Android\Sdk\platform-tools\adb.exe adb devices 查看连接的设备 adb shell getprop ro.build.version.release 查看系统版本 adb shell dumpsys window windows | findstr mFocusedApp 获取正在运行的app启动包名 结果为空,我不知道是不是Android…...
Java第四节:idea在debug模式夏改变变量的值
作者往期文章 Java第一节:debug如何调试程序(附带源代码)-CSDN博客 Java第二节:debug如何调试栈帧链(附带源代码)-CSDN博客 Java第三节:新手如何用idea创建java项目-CSDN博客 步骤一 在需要修改…...
Java学习手册:Java反射与注解
Java反射(Reflection)和注解(Annotation)是Java语言中两个强大的特性,它们在框架开发和复杂应用中扮演着重要角色。反射允许程序在运行时检查和操作类、对象、接口、字段和方法,而注解则提供了一种元数据形…...
21 天 Python 计划:MySQL事务四大隔离级别深度剖析
文章目录 一、事务1.1 什么是事务?1.2 事务的四大特性 二、事务并发存在的问题2.1 脏读(dirty read)2.2 不可重复读(unrepeatable read)2.3 幻读 三、事务的四大隔离级别实践3.1 读未提交(Read Uncommitted…...
IO多路复用沉浸式体验
这篇文章主要讲解一下IO多路复用常见问题,包含常见面试题,对你有帮助的话可以留个赞和关注嘛?谢谢大家支持! 1.epoll 相比于 select/poll 的优点有哪些? 高效的数据结构:epoll使用红黑树管理fd࿰…...
音视频学习(三十三):GOP详解
GOP 概念 GOP(图像组)是视频编码中一组帧的集合(按相关性分组),它从一个关键帧(I帧)开始,后面跟随若干个参考帧(P帧)和预测帧(B帧)。其结构决定了视频帧的压…...
部署YUM仓库
目录 一.YUM 1.1yum概述 1.2yum的实现 1.3yum服务的组成 1.4yum服务实现过程 1.5yum配置文件位置 二.yum相关命令 三.搭建yum仓库的方式 3.1使用HTTP方式搭建yum仓库 准备工作(服务端和客户端都需要做) 服务端 客户端 3.2使用ftp方式搭建yu…...
中位数学习(低估它了)
-----------------------------------------------------------------中位数------------------------------------------------------- 中位数有一个很好的性质:假设有一批数据,你想找一个数,使得这批数据与它差的绝对值的和最小࿰…...
音视频转换器 AV 接口静电保护方案
方案简介 音视频转换器是将音视频(AV)信号转换成其他格式或信号类型的设备或软件。 它能够实现大多数视频、音频以及图像格式之间的转换,包括但不限于 RMVB、AVI、 MP4、MOV 等常见格式,同时也支持将不同采样率、位深度、声道数…...
蓝桥杯嵌入式第十二届省赛程序设计1(超简单版)
此程序只需要会C语言数组,结构体(struct),for , if , switch(也可以用if)就能够实现。 引脚设置: 引脚配置(参照笔记): 代码部分: /* USER CODE END Header */ /* Includes ------------------…...
CSS 链接样式学习笔记
在网页设计中,链接(<a> 标签)是不可或缺的元素,通过 CSS 可以对链接进行丰富的样式设置,从而提升用户体验和页面美观度。以下是关于 CSS 链接样式的详细学习笔记。 一、链接的四种状态 链接有四种不同的状态&a…...
有ts文件却无法ts出来解决办法
一开始报错是报这个,但是我其实完全看不懂为什么 原因是这个 打开某个test就行了...
javaSE.Lambda表达式
如果一个接口中有且只有一个待实现的抽象方法,那么我们可以将匿名内部类简写为Lambda表达式。 简写规则 标准格式: (【参数类型 参数名称,】...) -> {代码语句, 包括返回值} 只有一行花括号{}可以省略。…...
Web渗透之文件包含漏洞
文件包含漏洞原理 1、源代码 <?php$filename $_GET[filename]; include $filename; //或include_once,require,require_onceecho "欢迎来到PHP的世界.";?> 2、利用条件 php.ini中alllow_url_fopenOn(默认开启)和allow_url_includeOff(默认关闭)要开启…...
费马引理和罗尔定理
cheer 向……欢呼,使高兴,欢呼,欢呼,愉快 前言区间平均值费马引理罗尔三步万能构造原函数的方法什么时候用罗尔定理计划拉格朗日需要记忆的不等式柯西中值定理泰勒高阶导数判断极值最后 前言 继续学习。今天争取把讲义和作业题都…...
【合新通信】浸没式液冷中低成本冷媒开发的最新进展
浸没式液冷光模块是一种结合高效散热技术与光通信的新型解决方案,主要用于数据中心、超算中心等高密度计算场景。其核心特点是通过将光模块直接浸入绝缘冷却液中(如矿物油、氟化液等),实现高效散热和节能降耗。低成本冷却液的研发…...
【开发记录】服务外包大赛记录
参加服务外包大赛的A07赛道中,最近因为频繁的DEBUG,心态爆炸 记录错误 以防止再次出现错误浪费时间。。。 2025.4.13 项目在上传图片之后 会自动刷新 没有等待后端返回 Network中的fetch /upload显示canceled. 然而这是使用了VS的live Server插件才这样&…...
智能指针之设计模式1
本文探讨一下智能指针和GOF设计模式的关系,如果按照设计模式的背后思想来分析,可以发现围绕智能指针的设计和实现有设计模式的一些思想体现。当然,它们也不是严格意义上面向对象的设计模式,毕竟它们没有那么分明的类层次体系&…...
Spring Boot 中应用的设计模式
Spring Boot 中应用的设计模式详解 Spring Boot 作为 Spring 框架的扩展,广泛使用了多种经典设计模式。以下是主要设计模式及其在 Spring Boot 中的具体应用: 一、创建型模式 1. 工厂模式 (Factory Pattern) 应用场景: BeanFactory 和 Ap…...
23种GoF设计模式
GoF(Gang of Four)设计模式是由四位计算机科学家 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 合著的书籍《Design Patterns: Elements of Reusable Object-Oriented Software》中提出的设计模式 目录 一、创建型模式(Cre…...
Python实例题:Python实现中文错别字高亮系统
目录 Python实例题 题目 安装依赖库 代码实现 代码解释 运行思路 注意事项 Python实例题 题目 Python实现中文错别字高亮系统 安装依赖库 在开始之前,你需要安装 pycorrector 和 rich 库。可以使用以下命令进行安装: pip install pycorrecto…...
【第三十一周】ViT 论文阅读笔记
ViT 摘要Abstract文章信息引言方法Patch EmbeddingPatch Position EmbeddingTransformer EncoderMLP Head整体架构CNN的归纳偏置 代码实现实验结果总结 摘要 本篇博客介绍了Vision Transformer(ViT),这是一种突破性的图像分类模型ÿ…...
射频(RF)静电放电防护方案
方案简介 射频(RF)是 Radio Frequency 的缩写,表示可以辐射到空间的电磁频率,频率 范围从 300kHz~300GHz 之间。射频就是射频电流,简称 RF,它是一种高频交流变化 电磁波的简称。射频天线是一…...
【redis进阶三】分布式系统之主从复制结构(1)
目录 一 为什么要有分布式系统? 二 分布式系统涉及到的非常关键的问题:单点问题 三 学习部署主从结构的redis (1)创建一个目录 (2)进入目录拷贝两份原有redis (3)使用vim修改几个选项 (4)启动两个从节点服务器 (5)建立复制,要想配…...
排序(1)
排序(1) 日常生活中,有很多场景都会用到排序。比如你买东西,在购物软件就有几种展现方式,按照评论数量给你排序出来,让你选,还是说按照价钱高低排序出来让你选。 排序其实是一种为了更好解决问…...
NR 5G中的N5接口
N5接口的定义: Reference point between the PCF and an AF or TSN AF. 即N5 PCF和AF之间的参考点。 AF Application Function 应用功能,指应用层的各种服务,可以是运营商内部的应用如Volte AF(类似4G的Volte As)、也可以是第三方的AF&…...
STM32自学进阶指南:从入门到精通的成长路径 | 零基础入门STM32第九十九步
主题内容教学目的/扩展视频自学指导通过数据手册和搜索引擎查找资料,独立解决问题以积累经验和提升能力。自学过程中应保持敬畏之心,不断总结未知领域,持续进步。师从洋桃电子,杜洋老师 📑文章目录 一、自学指导全景图1.1 学习路线对比1.2 关键学习策略二、待探索技术领域…...
利用 Python 进行股票数据可视化分析
在金融市场中,股票数据的可视化分析对于投资者和分析师来说至关重要。通过可视化,我们可以更直观地观察股票价格的走势、交易量的变化以及不同股票之间的相关性等。 Python 作为一种功能强大的编程语言,拥有丰富的数据处理和可视化库…...
用 Vue.js 构建基础购物车:从 0 到 1 的实战解析
在当今数字化购物的浪潮中,购物车功能已成为电商平台不可或缺的一部分。它不仅承担着记录用户所选商品的重任,还需提供流畅的交互体验和精准的计算逻辑。本文将深入探讨如何利用 Vue.js 这一强大的 JavaScript 框架,逐步搭建一个基础但功能完…...
MapSet常用的集合类(二叉搜索树,哈希表)
Set集合 Set的核心特点: Set继承了Collection。 保存的元素不会重复。 保存的元素不能修改。 保存的元素无序,和List不同,如果有两个:List {1,2,3},List {2,1,3}&…...
五种IO模型
1、通信的本质: 通过网络通信的学习,我们能够理解网络通信的本质是进程间通信,而进程间通信的本质就是IO。 IO也就是input和output。当读取条件不满足的时候,recv会阻塞。write写入数据时,会将数据拷贝到缓冲区中&am…...
路由器开启QOS和UPNP的作用
QOS 的作用 保障关键业务带宽:可根据网络应用的重要性分配带宽。比如在家庭网络中,当多人同时使用网络时,将视频会议等实时性要求高的关键业务设置为高优先级,确保其能获得足够带宽,避免卡顿,而文件下载等…...
学习MySQL的第九天
纸上得来终觉浅 绝知此事要躬行 数据处理的增删查改 一、添加数据 添加数据有两种方式,一种是一条一条的添加数据,另一种是通过对其他表的查询,将查询的结果插入到表中;第一种方式又可以分为三种方式:…...
怎么免费下载GLTF/GLB格式模型文件,还可以在线编辑修改
现在非常流行glb格式模型,和gltf格式文件,可是之类模型网站非常非常少 1,咱们先直接打开http://glbxz.com 官方glb下载网站 glbxz.com 2 可以搜索,自己想要的模型关键词 3,到自己想下载素材页面 4,…...
高效数据拷贝方法总结
1.系统/语言层面的高效拷贝 内存拷贝优化 使用memcpy(C/C)或类似函数进行大块内存拷贝 利用SIMD指令(如AVX/SSE)进行向量化拷贝 2.零拷贝技术 文件映射(mmap) - 将文件映射到内存空间 发送文件描述符而非数据本身(Unix域套接字) 使用sendfile系统调用(文件到套接字直接传…...
C 语言 第八章 文件操作
目录 文件操作 文件和流的介绍 C 输入 & 输出 C 文件的读写 创建/打开文件 写入文件 fputc 函数 fputs 函数 fprintf 函数 实例: 读取文件 fgets函数 实例: 关闭文件 文件操作 文件和流的介绍 变量、数组、结构体等数据在运行时存储于内存…...
开发一款游戏需要哪些岗位角色参与?
常见分类 1. 游戏策划(Game Designer) 核心职责:设计游戏的玩法、规则、内容和整体体验。 具体工作: 系统设计:设计游戏的战斗、经济、成长、社交等核心系统。 数值设计:平衡角色属性、装备数值、经济系…...
大模型面经 | 手撕多头注意力机制(Multi-Head Attention)
大家好,我是皮先生!! 今天给大家分享一些关于大模型面试常见的面试题,希望对大家的面试有所帮助。 往期回顾: 大模型面经 | 春招、秋招算法面试常考八股文附答案(RAG专题一) 大模型面经 | 春招、秋招算法面试常考八股文附答案(RAG专题二) 大模型面经 | 春招、秋招算法…...
二叉树的初步学习
前言 对于二叉树的学习不想其他数据结构一样,直接学习他的结构的构建。单纯的一个二叉树在实际中没什么作用,除非是加了限制条件的,比如大名鼎鼎的红黑树。但是对于初学者而言,刚开始就学习红黑树,会让你刚接触就想放…...
Tkinter菜单和工具栏的设计
在这一章中,我们将深入探讨如何在Tkinter应用程序中设计菜单和工具栏。菜单和工具栏是桌面应用程序中常见的界面元素,它们为用户提供了便捷的操作方式。通过这一章的学习,您将能够在您的Tkinter应用中添加菜单栏和工具栏,提升用户体验。 6.1 菜单栏的设计 菜单栏是应用程…...
windows中搭建Ubuntu子系统
windows中搭建虚拟环境 1.配置2.windows中搭建Ubuntu子系统2.1windows配置2.1.1 确认启用私有化2.1.2 将wsl2设置为默认版本2.1.3 确认开启相关配置2.1.4重启windows以加载更改配置 2.2 搭建Ubuntu子系统2.2.1 下载Ubuntu2.2.2 迁移位置 3.Ubuntu子系统搭建docker环境3.1安装do…...
Docker 部署 Kafka 完整指南
Docker 部署 Kafka 完整指南 本指南将详细介绍如何使用 Docker 部署 Kafka 消息队列系统,包括单节点和集群模式的部署方式。 1. 单节点部署 (Zookeeper Kafka) 1.1 创建 docker-compose.yml 文件 version: 3.8services:zookeeper:image: bitnami/zookeeper:3.8…...