Educational Codeforces Round 126 (Rated for Div. 2)

A .   A r r a y   B a l a n c i n g A.\ Array\ Balancing A. Array Balancing

题意:

可以选择 i i i通过交换 a i , b i a_i,b_i ai,bi使相邻元素之间的差值之和最小。

这题猜了好长时间思路一直不对,但是其实很好想,运用宏观思维的话,因为这是两个序列,那肯定是小的和小的放在一起,大的与大的放在一起呀,

当然这样可能不太严谨,不过这只是个 A A A题QAQ

\令人头秃

#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 60;
int a[N],b[N];
int n;
void solve()
{
    cin >> n;
    for(int i=1;i<=n;i++) cin >> a[i];
    for(int i=1;i<=n;i++) cin >> b[i];
    for(int i=1;i<=n;i++){
        if(a[i]>b[i]) swap(a[i],b[i]);
    }
    int res=0;
    for(int i=1;i<n;i++){
        res+=abs(a[i]-a[i+1]);
        res+=abs(b[i]-b[i+1]);
    }
    cout << res << endl;
}
signed main(){
    int t; cin >> t;
    while(t--) solve();
    return 0;
}

在这里插入图片描述

当然这里面的第一种方法我是没看懂的,但是第二种看起来很简单,那就是一对一对地比较交换前后的变化,如果交换之后绝对值之和变小了那就交换,就这样遍历完两个序列。

(感觉还是挺暴力的,我甚至马上排除了这种做法。。。)

B .   G e t t i n g   Z e r o B.\ Getting\ Zero B. Getting Zero

(这道题目好有趣!*…*)

又是一道有关位运算的题目!一生之敌!!!、

但是不得不说位运算真的很奇妙!但也很令人(我)头秃!

这道题目:

首先我们可以发现题目给的模数非常特别!我没发现QAQ

众所周知 32768 32768 32768 2 2 2 15 15 15次方,对这个数取模就很怪(?)

32768 = ( 1000   0000   0000   0000 ) B 32768=(1000\ 0000\ 0000\ 0000)_B 32768=(1000 0000 0000 0000)B

当我们把给定的数都用二进制表示:

19 = ( 10011 ) B 19=(10011)_B 19=(10011)B 此时如果我们将他加 1 1 1,那么直观的,它变成了 20 20 20,不直观地,但也挺直观的,它变成了 ( 10100 ) B (10100)_B (10100)B,如果此时我们将他右移 15 − 2 = 13 15-2=13 152=13位,那么他将会以 1000   0000   0000   0000 1000\ 0000\ 0000\ 0000 1000 0000 0000 0000结尾,也就是说他能被这个数整除了,那取模就是 0 0 0了。

就是这么个思路,但是具体要加多少个 1 1 1和左移多少位合适,是要枚举一下的。

当然要看清数据范围, n n n取不到 0 0 0,但! a a a可以取到,睁开眼睛啊!

但是 0 0 0要特判一下,上述写法 0 0 0过不了QAQ(因为WA了)

还有 r e s res res记得每次都要更新。

#include <bits/stdc++.h>
using namespace std;

int a;
signed main(){
    int n,res=20; cin >> n;
    while(n--)
    {
        res=20;
        cin >> a;
        if(a==0){
            cout << 0 << ' ';
            continue; 
        }
        for(int i=0;i<=15;i++)
        {
            int add=i,cnt0=0;
            for(int j=0;j<=15;j++){
                if(((a+add)>>j)&1) break;//右移直到最低位是1就结束,这样结束的时候cnt0记录的是最低位的0地数量(也就是不再需要左移的位数)
                cnt0++;
            }
            res=min(res,add+15-cnt0);//加1的操作数与需要左移的操作数
        }
        cout << res << ' ';
    }
    return 0;
}

其实代码中的记录 0 0 0的数量那一步想用 l o w b i t lowbit lowbit来实现来着,感觉本质上差不多,但是暂时还没想要怎么写,先写过再说。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值