IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Codeforces Round #759 (Div. 2 based on Technocup 2022 Elimination Round 3)(A~D)题解 -> 正文阅读

[数据结构与算法]Codeforces Round #759 (Div. 2 based on Technocup 2022 Elimination Round 3)(A~D)题解

Codeforces Round #759 (Div. 2, based on Technocup 2022 Elimination Round 3)

这场时间太阴间了,十一点开场还延时两次,可怜早八人迟到;
不过昨天打的小号,今天算分的时候小号的分数
请添加图片描述
感谢codeforces在博主生日这天给予的浪漫QAQ(贴贴);

A. Life of a Flower

题目:——>传送门

题意:给一束花,初始的高度为1,之后过了n天,在这n天中,对于第i天如果浇水,则花高度加1,若i-1天也浇了水,则花的高度额外加4,当持续两天没有浇水,则花会枯萎此时高度为-1,给出每天的浇水状态,问第n天花的高度;

解题思路:数据范围不大,直接模拟得出最后的答案;

AC代码

int a[105];
 
void solve(){
    int n;
    scanf("%d", &n);
    for(int i = 1; i<=n; i++) scanf("%d", &a[i]);
    int ans = 1;
    int res = 0;
    for (int i = 1; i <= n; i ++ ){
        if(a[i] == 1){
            if(a[i-1] == 1) ans+=5;
            else ans+=1;
            res = 0;
        }
        else res++;
        if(res == 2){
            ans = -1;
            break;
        }
    } 
    cout<<ans<<endl;
}
 
int main()
{
    int t;
    scanf("%d", &t);
    while(t--){
        solve();
    }
    return 0;
}

B. Array Eversion

题目:——>传送门

题意:给出一个任意序列的数组,每次可以对于数组末尾的数字x对数组的顺序进行改变,规则为:对于最后一数x将小于等于x的数放到x的左边,大于x的数放到x的右边(注:各部分元素的顺序与操作前保持一致,例如原序列[4,2,1,5,3]会变成[2,1,3,4,5]),求需要经过几次才能使得序列无法做出改变;

解题思路:首先数组无法做出改变的终止条件就是当最后一个数为数组中最大的数,对于每一个x(x即当前数组最后的元素),每次改变都可以将x前连续的小于等于x的数移到左边,也就是说,下一个末尾的数是当前的x前第一个大于x的数,一次类推,直到末尾数为数组最大值;

AC代码

const int N = 2e5+5;
int a[N];
 
void solve(){
    int n;
    scanf("%d", &n);
    for(int i = 1; i<=n; i++) scanf("%d", &a[i]);
    int ans = a[n];
    int res = 0;
    for(int i = n-1; i; i--){
        if(a[i]>ans){
            ans = a[i];
            res++;
        }
    }
    cout<<res<<endl;
    return;
}
 
int main()
{
    int t;
    scanf("%d", &t);
    while(t--){
        solve();
    }
    return 0;
}

C. Minimize Distance

题目:——>传送门

题意:给出一个数组a,其中a[i]表示第i个仓库在数轴上的位置(包含负数,a[i]的值可能相同),每个仓库需要一袋产品,每次可以从数轴0的位置携带k袋产品前往各个仓库,问最少需要经历的路程为多少?(注:当走到最后一个仓库时不用返回原点);

解题思路:很明显的贪心题,贪心思路还是很好想的,将正数和负数分开考虑,再从大到小模拟需要走过的路程,最后减去正数和负数中绝对值最大的数(这个仓库为最后去的,不用返回);详情见代码注释;

AC代码

typedef long long ll;
const int N = 2e5+5;
int a[N];
int b[N];
 
void solve(){
    int n, k;
    scanf("%d%d", &n, &k);
    int x;
    int cnt = 0, tot = 0;
    for(int i = 1; i<=n; i++){
        scanf("%d", &x);
        if(x>0) a[++cnt] = x;//正数和负数分类讨论
        if(x<0) b[++tot] = -x;
    }
    sort(a+1, a+cnt+1);sort(b+1, b+tot+1);//从小到大排序
    ll ans = 0;
    for(int i = cnt; i>=0; i-=k){//从最远的仓库开始,每次走过k个仓库,则下次去的仓库为第i-k远的仓库
        ans+=(ll)a[i]*2ll;//路程来回,需要乘2;
    }
    for(int i = tot; i>=0; i-=k){//同上
        ans+=(ll)b[i]*2ll;
    }
    ans-=max(a[cnt], b[tot]);//去所有仓库中最远的仓库的那一次运送所走的路程,该次可以不用回到原点;
    cout<<ans<<endl;
    return;
}
 
int main()
{
    int t;
    scanf("%d", &t);
    while(t--){
        solve();
    }
    return 0;
}

D. Yet Another Sorting Problem

题目:——>传送门

题意:给定一个任意序列的数组a,每次可以选择其中的三个位置i,j,k(1≤i,j,k≤n),令他们位置上的数发生传递周期改变 i→j→k→i ,将ai放在位置j,aj放在位置k,ak放在位置i,而不改变任何其他元素,问做出若干次这样的改变能否将数组变为不递减的顺序;

解题思路:考虑变化中逆序对数量的改变,首先对与不递减的数组逆序数量为0,而对于给定的操作,每次逆序对的变化都是偶数(证明如下);

证明:设a,b,c为其中改变的三个位置上的数;
设数组形式为:a……b……c,其中第一段……有n个数,第二段……有m个数;
此时做出改变后:c……a……b;

对于c:设第一段中有x个数大于c,第二段中有y个数大于c,两段中对于c的逆序对为(x+y)个,此时将c变到原来a的位置,则第一段中有n-x个数小于c,第二段中有m-y个数小于c,对于c的逆序对从(x+y)变成了(n-x+m-y),变化量为(n-2x+m-2y);
对于b:设第一段中有t个数大于b,第二段中有k个数小于b,两段中对于b的逆序对为(t+k)个,此时将b变到原来c的位置,则第一段中有t个数大于b, 第二段中有m-k个数大于c,对于b的逆序对数量从(t+k)变到(t+m-k),变化量为(m-2k);
对于a:设第一段中有p个数小于a,第二段中有q个数小于a,两段中对于b的逆序对为(p+q)个,此时将a变到原来b的位置,则第一段中有n-p个数大于a, 第二段中有q个数小于a,对于a的逆序对数量从(p+q)变到(n-p+q),变化量为(n-2p);

将上述变化量加起来为n-2x+m-2y+m-2k+n-2p = 2n-2m-2x-2y-2k-2p = 2(n-x-y-k-p);而对于a,b,c之间做周期改变,所以a,b,c之间逆序对数目不发生改变(除非其中有两个数相同),则逆序对变化量一定是偶数

则可以求出原序列的逆序对的奇偶性,看是否为偶排列,特别的如果序列中一个元素的个数超过了1,则可以通过周期改变将奇排列变为偶排列(这种情况也可以);

AC代码

const int N = 5e5+5;
int a[N];
int tr[N*2];
int n; 
 //树状数组用于求逆序对的数量
int lowbit(int x){
    return x&-x;
}
 
int sum(int n){
    int ans = 0;
    for(int i = n; i; i-=lowbit(i)) ans+=tr[i];
    return ans;
}
 
void add(int x){
    for(int i = x; i<=n; i+=lowbit(i)) tr[i]++;    
}
 
void solve(){
    scanf("%d", &n);
    unordered_map<int, int> ma;
    int ans = 0;
    for(int i = 1; i<=n; i++) scanf("%d", &a[i]), ma[a[i]]++, ans = max(ans, ma[a[i]]);
    if(ans>=2){
        puts("YES");
        return;
    }
    ans = 0;
	for (int i = 1; i<=n; i++) {
		ans += sum(n) - sum(a[i]);
		add(a[i]);
	}
	if(ans%2 == 0) puts("YES");
	else puts("NO");
	for(int i = 1; i<=n+3; i++) tr[i] = 0;
    return;
}
 
int main()
{
    int t;
    scanf("%d", &t);
    while(t--){
        solve();
    }
    return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-12-14 16:12:59  更:2021-12-14 16:14:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 16:40:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码