牛客寒假算法训练营3

A(签到)

数据范围小 预处理一下所有合法的数查询即可

B(GCD)

题意:判断数组中是否存在两个数字的gcd大于1

暴力:由于随机数据 并且只需要找到一组 所以数据不会故意放在遍历的最后一次 直接两层循环暴力即可解决

第二种思路是 对每个数组 分解质因数 然后用map维护每个质因数上次出现的位置 如果一个质因数出现了两次 那么输出这两个位置即可

第二种思路代码:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
vector<int>f(int x){
	vector<int>v;
	for(int i=2;i*i<=x;i++){
		if(x%i==0){
			v.push_back(i);
			while(x%i==0)x/=i;
		}
	}
	if(x>1)v.push_back(x);
	return v;
}
void solve(){
	int n;cin>>n;
	vector<int>a(n);
	for(int i=0;i<n;i++)cin>>a[i];
	map<int,int>mp;
	for(int i=0;i<n;i++){
		int x=a[i];
		vector<int>fs=f(x);
		for(int p:fs){
			if(mp.count(p)){
				cout<<mp[p]<<" "<<x<<"\n";
				return;
			}
		}
		for(int p:fs)mp[p]=x;
	}
	cout<<"-1\n";
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	int T;cin>>T;
	while(T--)solve();
	return 0;
}

C(构造、前缀和、Kadane(最大子段和))

大致题意: 01串每次可以选择一个交替串01反转 目标是将所有串都变为交替串

我们的目标串只有0101010 和1010101 两种 我们可以分别以两个目标串为目标都做一遍 然后取最小值 对于一种目标串 我们将错误的部分提取出来 成为一个字串 我们用c1 c0维护当前以1 或 0 结尾的子序列有几个 遍历一遍需要改变的部分 如果为0 那么结尾为1 的串-1 结尾为0的串+1 若没有则新开一个串 0 结尾 以此类推

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int check(string s){
    int c1=0,c0=0;
    for(auto x:s){
        if(x=='1'){
            if(c0==0)c1++;
            else c1++,c0--;
        }else if(x=='0'){
            if(c1==0)c0++;
            else c1--,c0++;
        }
    }
    return c0+c1;
}
void solve(){
    int n;cin>>n;
    string s;
    cin>>s;
    string s1,s2;
    for(int i=0;s[i];i++){
        if((i%2==1&&s[i]=='0')||(i%2==0&&s[i]=='1'))s1.push_back(s[i]);
        if((i%2==1&&s[i]=='1')||(i%2==0&&s[i]=='0'))s2.push_back(s[i]);
    }
    cout<<min(check(s1),check(s2))<<'\n';
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;cin>>t;
    while(t--)solve();
    return 0;
}

F(博弈、最短路、构造)

要到达n列 那么要往右n-1次 剩下的就是不得不向另一方向走的路径

观察可得 每五列都会有一次强制换行 所以答案为n-1+n/5

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long

void solve(){
    int n;
    cin>>n;
    cout<<n-1+n/5<<"\n";
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int _;
    cin>>_;
    while(_--)solve();
    return 0;
}

G(排序)

要改变砝码状态 我们肯定要优先选择大的砝码拿走 可以排序后直接遍历一遍即可 直到状态改变 或者不排序 直接存到大根堆里面 每次拿出堆顶

代码如下:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
#define int long long
int a[N],b[N];
int n,m;
void solve(){
    cin>>n>>m;
    priority_queue<int>aq,bq;
    int ans=0;
    long long suma=0,sumb=0;
    for(int i=1;i<=n;i++)cin>>a[i],aq.push(a[i]),suma+=a[i];
    for(int i=1;i<=m;i++)cin>>b[i],bq.push(b[i]),sumb+=b[i];
    if(suma==sumb)ans=1;
    else if(suma>sumb){
        while(suma>sumb){
            int u=aq.top();aq.pop();
            suma-=u;
            ans++;
        }
    }else if(sumb>suma){
        while(sumb>suma){
            int u=bq.top();bq.pop();
            sumb-=u;
            ans++;
        }
    }
    cout<<ans<<'\n';

}
signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;cin>>t;
    while(t--)solve();    
    return 0;
}

H(计算几何)

向量叉乘 推一下面积公式 然后直接做即可

此处给py代码 cpp要注意精度

python 复制代码
xa,ya=input().split()
xb,yb=input().split()
xa=float(xa)
ya=float(ya)
xb=float(xb)
yb=float(yb)
dy=ya-yb
if abs(dy)<0.000000001:
    area=0.5*abs(ya*(xa-xb))
    if abs(area-2)<0.000001:
        print("0")
    else:
        print("no answer")
else:
    D=xa*yb-ya*xb
    x=(-D+4)/dy
    print(x)

J(二叉树/二进制)

求完全二叉树某一层的节点个数

对于全满的某一层 若深度为d 那么就有2^(d-1)个 所以判断一下深度即可 如果询问的层数不是最后一层 那就满 否则减去前几层就行了

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
int depth(int x) {
    int d = 0;
    while ((1LL << (d + 1)) <= x) {
        d++;
    }
    return d;
}
void solve() {
    int n, q;
    cin >> n >> q;
    while (q--) {
        int x;
        cin >> x;
        int d = depth(x); 
        int start = (1LL << d); 
        int end = min(n, (1LL << (d + 1)) - 1); 
        cout << (end - start + 1) << '\n';
    }
}
signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}
相关推荐
今儿敲了吗2 小时前
32| 伐木
数据结构·笔记·学习·算法
样例过了就是过了2 小时前
LeetCode热题100 环形链表
算法·leetcode·链表
努力学算法的蒟蒻2 小时前
day95(2.24)——leetcode面试经典150
算法·leetcode·面试
ZPC82102 小时前
window 下使用docker
人工智能·python·算法·机器人
DaisyMosuki2 小时前
个人实现大数加减乘(高精度加减乘)
算法·高精度·大数
郭逍遥2 小时前
[Godot] 通过AABB包围盒和射线法检测碰撞
算法·游戏引擎·godot
大黄说说2 小时前
解锁 .NET 性能极限:深入解析 Span 与零拷贝内存艺术
java·数据结构·算法
知识即是力量ol2 小时前
深入理解 Snowflake 雪花算法:原理、本质、趋势递增问题与分布式顺序困境全解析
java·分布式·算法·雪花算法·snowflake·全局唯一id·分布式id生成器
啊阿狸不会拉杆2 小时前
《计算机视觉:模型、学习和推理》第 11 章-链式模型和树模型
人工智能·学习·算法·机器学习·计算机视觉·hmm·链式模型