Codeforces Global Round 18(A-C)

本文介绍了三道编程竞赛题目,涉及序列操作、按位与运算和字符串转换。A题中,通过分析序列和,确定将所有数变为相等或差1的最小操作数;B题中,计算按位与非零的最少去除数,利用前缀和优化求解;C题中,探讨如何通过特定操作将字符串a转换为b,分析不同情况下的操作次数。

Codeforces Global Round 18(A-C)

第一次写,表达不清晰的请见谅。

A.Closing The Gap

题意:

给一个序列a,每次操作可以让序列a中一个数加1和另一个数减1

在多次操作后,问max(a)−min(a)max(a) - min(a)max(a)min(a)的最小值。


思路:

不难发现,我们的总和是不变的。在没有操作次数的限制下,我们一定可以把所有数弄相等或者差1。所以我们只需要算出总和看能不能平分,可以的话答案就是0,否则就是1。


代码

#include<bits/stdc++.h>
#include<set>
#include<deque>
#include<map>
 
using namespace std;
typedef long long ll;
typedef pair<ll,ll>PII;
const int N = 1e6+10,inf = 0x3f3f3f3f;
int a[N];
 
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
 
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        ll sum = 0;
        for(int i = 1; i <= n; i++){
            cin >> a[i];
            sum += a[i];
        }
        if(sum % n == 0){
            cout << 0 << endl;
        }
        else{
           cout <<1<<endl;
        }
    }
    return 0;
}
/*
input
3 			
3       	
10 10 10	
4
3 2 1 2
5
1 2 3 1 5	
output
0
0
1
*/

B.And it’s Non-Zero

题意:

给一个l(左边界)r(右边界),我们的目的是找到 最少从l到r的所有数中取去多少数后,

可以让l到r这个区间的按位与运算结果非0。


思路:

因为按位与是有0得0

要使答案非0,我们就要保证最后留下的每个数其二进制中在某个相同的位置全是1。

我们只需要在二进制中寻找每个数中每一位出现1的次数,找到出现次数的最大值。

这就说明这是我们需要留下的数。我们再用区间长度去减去它便可得到答案——要取出的数。

我们可以发现数据范围是2e52e52e5 也就是说我们的数转换为二进制最多就20位

我们需要计算出一个区间中每个数每一位1出现的次数,在测试组数为1e41e41e4的情况下,我们每次都去跑完区间是肯定会TleTleTle(我就tle了) ,所以我们要提前初始化数据。

#include<bits/stdc++.h>
#include<set>
#include<deque>
#include<map>

using namespace std;
typedef long long ll;
typedef pair<ll,ll>PII;
const int N = 2e5+10,inf = 0x3f3f3f3f;
int a[N][20]; // a[i][j] = 1 表示1——i之间所有数在其二进制下第j位上有1个1

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    //计算从1到2e5中每个数中二进制每一位1的个数
    for(int i = 1; i <= N; i++){
        for(int j = 0 ; j < 20 ; j ++){
            if(i & (1 << j) ) a[i][j]++;
            a[i][j] += a[i-1][j]; // 前缀和维护
        }
    }

    int t;
    cin >> t;
    while(t--){
        int l , r;
        cin >> l  >> r;
        int ans = 0;
        //找到这个区间中二进制1出现最多的次数
        for(int i = 0; i <20; i++){
            ans = max(ans,a[r][i] - a[l-1][i]);
        }
        ans = (r - l + 1) - ans;
        cout << ans <<endl;
    }
    return 0;
}
/*
input
5
1 2
2 8
4 5
1 5
100000 200000
output
1
3
0
2
31072
*/

C.Menorah

题意:

给两个由1和0组成的字符串 a,b。我们每次可以对a串的1进行操作:

维持当前位置1不变,其他位置的1变成0,0变成1;

问我们能否通过该操作把a串变成b串,如果可以 就输出最小操作次数,否则输出-1

思路:

通过观察,我们可以发现:

/*
1010 我们操作为1 的位置1
 |
1101 我们再操作原先为 0 的位置2
 |
0110 (结果)
*/

相当于我们可以通过两次操作交换原串中1和0的位置,并让其他位置保持不变。

于是:交换一次位置我们就要操作两次


我们要把从a串状态变成b串:

计算不相等的位置中 a串1与0的数量是否相等,相等的话我们可以用交换操作达成目的此时答案是

交换次数 * 2


特殊情况:

如果a串与b串中有同一位置等于1

我们就可以优先操作该位置,操作后该位置不变,之前与b串不相等的地方会相等,相等的地方会不等

/*
a:101   0101
b:101   1010
操作位置1
a:1  10   1010
b:1  01   1010
*/

所以我们也可以计算原a串中相同位置的0与1的数量是否相等,相同1的数量要减1(减去用来翻转的第一次),如果相同,我们同样可以通过交换操作达成目标,此时答案是交换次数 * 2 + 我们第一次的1次翻转


两个情况取最小值既是答案

#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
using namespace std;
const int N = 1e5 + 5;
const int INF = 0x3f3f3f3f;
typedef long long ll;
typedef pair<int,int> pe;
int a[N];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int t;
    cin >> t;
    while(t -- ){
        int n;
        cin >> n;
        string a , b;
        cin >> a >> b;
        int len = a.length();
        int ans = INF;
        int an = 0, bn = 0, cn = 0, dn = 0;
        for(int i = 0; i < len; ++ i){
            if(a[i] != b[i]){
                if(a[i] == '1') an++;
                else bn ++;
            }
            if(a[i] == b[i]){
                if(a[i] == '1') cn++;
                else dn ++;
            }
        }
        if(an == bn) ans = min(ans , an * 2);
        if(cn){
            cn --;
            if(cn == dn) ans = min(ans , cn * 2 + 1);
        }
        if(ans == INF) cout << - 1 << endl;
        else cout << ans << endl;
    }

    return 0;
}

内容概要:本文围绕可变桨叶四旋翼无人机的规范控制与点对点运动模拟展开,重点研究优化推力分配策略在翻转动作中的应用与性能比较。通过Matlab代码实现,构建了四旋翼动力学模型,并设计了多种控制算法以实现精确的姿态调整与轨迹跟踪。研究对比了不同推力分配方案在执行高机动性翻转动作时的稳定性、能耗效率与响应速度,旨在提升无人机在复杂飞行任务中的动态性能与控制精度。该仿真研究为无人机飞控系统的设计与优化提供了理论依据和技术支持。; 适合人群:具备一定自动控制理论基础和Matlab编程能力,从事无人机控制、飞行器动力学或机器人系统研究的科研人员及研究生。; 使用场景及目标:① 实现四旋翼无人机在三维空间中的精确点对点运动控制;② 对比分析不同推力分配策略在执行翻转等高难度动作时的控制效果与能耗表现,优化飞行性能;③ 为无人机自主飞行、特技飞行及复杂环境下的机动控制提供算法验证平台。; 阅读建议:此资源以Matlab仿真为核心,建议读者结合相关控制理论知识,深入理解代码实现细节,重点关注动力学建模、控制律设计与推力分配模块。在学习过程中,应动手调试参数,复现文中翻转动作的仿真结果,并尝试拓展至其他复杂飞行任务,以加深对无人机控制机理的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值