Codeforces Round #694 (Div. 2) B. Strange List

先上题的链接 link
看了大佬的思路后,决定写文章记录一下。
这是大佬的题解 link

题意
t组输入(惯用套路),输入n,x,再输入n个数(先记为a数组)。
开始操作:
(从数组第一个数到最后一个数)
如果a[i] % x == 0,那么将x个(a[i] / x)甩入数组末尾;
如果a[i] % x != 0,那么结束操作。
输出操作后数组a中所有数字的和。

思路:
刚开始用队列写的,一直卡在第5个测试点(不太聪明的亚子)
举个例子:
假设数组只有16这个数,x = 2
0: 16
1: 16 (8 8)
2: 16 (8 8) 4 4
3: 16 (8 8) (4 4 4 4)
4: 16 (8 8) (4 4 4 4) 2 2
··· ···
7: 16 (8 8) (4 4 4 4) (2 2 2 2 2 2 2 2)
··· ···
15: 16 (8 8) (4 4 4 4) (2 2 2 2 2 2 2 2) (1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 )
------------结束
最后的和就是5个16相加,换句话来说就是16最多可以被24整除,再算上自己本身,那么这个5就可以由4+1得来

那么复杂一点的话,将数组变成4 2 16呢(x仍为2)
0: 4 2 16
1: 4 2 16 (2 2)
2: 4 2 16 (2 2) (1 1)
3: 4 2 16 (2 2) (1 1) (8 8)
4: 4 2 16 (2 2) (1 1) (8 8) 1 1
5: 4 2 16 (2 2) (1 1) (8 8) (1 1 1 1)
------------结束
可以发现结束操作在哪个数 取决于初始时能整除x的次数最少的那个数,将此次数记为cnt。
在这个例子中cnt = 1,而结束操作时 追溯到最根本是初始时的2,最终数组有(2 + 1)个4,(1 + 1)个2,(1 + 1)个16
即(cnt + 1 + 1)个4,(cnt + 1)个2,(cnt + 1)个16
斜体的“+ 1”表示自己本身,在2之前的数做了cnt + 1次的操作,在2包括2之后的数做了cnt次的操作。

就是说 找到数组中整除x的次数最少的数字,并记录该次数cnt和该数的位置p
最终答案就是a[i] * (cnt + 1 + 1) + a[j] * (cnt + 1)。 (其中0 <= i < p, p <= j < n)

上AC代码!!

#include <iostream>
#include <algorithm>
#define ll long long

using namespace std;

const int N = 1e5 + 10;

ll a[N];

int main()
{
    int t;
    cin >> t;
    while(t --)
    {
       ll n, x;
       cin >> n >> x;
       ll y, p, cnt = 1e5;
       for (ll i = 0; i < n; i ++ )
       {
           cin >> a[i];
           y = 0;
           for (ll j = x; ; j *= x) //找每个数能整除x几次
               if(a[i] % j == 0) y ++;
               else break;
           if(y < cnt) p = i, cnt = y;
       }
       ll sum = 0;
       for (ll i = 0; i < p; i ++ ) sum += (cnt + 2) * a[i];
       for (ll i = p; i < n; i ++ ) sum += (cnt + 1) * a[i];
       cout << sum << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

“老船”

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值