2023-01-02:某天,小美在玩一款游戏,游戏开始时,有n台机器,
每台机器都有一个能量水平,分别为a1、a2、…、an,
小美每次操作可以选其中的一台机器,假设选的是第i台,
那小美可以将其变成 ai+10^k(k为正整数且0<=k<=9),
由于能量过高会有安全隐患,所以机器会在小美每次操作后会自动释放过高的能量
即变成 (ai+10^k)%m
其中%m表示对m取模,由于小美还有工作没有完成,所以她想请你帮她计算一下,
对于每台机器,将其调节至能量水平为0至少需要多少次操作
(机器自动释放能量不计入小美的操作次数)。
第一行两个正整数n和m,表示数字个数和取模数值。
第二行为n个正整数a1, a2,… an,其中ai表示第i台机器初始的能量水平。
1 <= n <= 30000,2 <= m <= 30000, 0 <= ai <= 10^12。
来自美团。

答案2023-01-02:

打表法。
用rust和solidity写代码。

代码用rust编写。代码如下:

use std::iter::repeat;
fn main() {
let n = 5;
let m = 11;
let mut arr = vec![1, 3, 5, 7, 9];
let ans = times(n, m, &mut arr);
println!("ans = {:?}", ans);
} fn times(n: i32, m: i32, arr: &mut Vec<i32>) -> Vec<i32> {
// map[i] : i这个余数变成余数0,需要至少操作几次?
let mut map: Vec<i32> = repeat(0).take(m as usize).collect();
bfs(m, &mut map);
let mut ans: Vec<i32> = repeat(0).take(n as usize).collect();
for i in 0..n {
let num = arr[i as usize];
let mut min_times = i32::MAX;
if num < m {
min_times = map[num as usize];
} else {
let mut add: i64 = 1;
while add <= 1000000000 {
let mod0: i32 = ((num as i64 + add) % m as i64) as i32;
min_times = get_min(min_times, map[mod0 as usize] + 1);
add *= 10;
}
}
ans[i as usize] = min_times;
}
return ans;
} fn bfs(m: i32, map: &mut Vec<i32>) {
let mut visited: Vec<bool> = repeat(false).take(m as usize).collect();
visited[0] = true;
let mut queue: Vec<i32> = repeat(0).take(m as usize).collect();
let mut l = 0;
let mut r = 1;
// map[0] == 0
// 表示余数0变成余数0,需要至少0次
// 0进队列了, queue[0] = 0
// 0算访问过了,visited[0] = true
while l < r {
// 当前弹出的余数是cur
let cur = queue[l as usize];
l += 1;
// 能加的数字,从1枚举到10^9
let mut add: i64 = 1;
while add <= 1000000000 {
// 比如,m == 7
// 当前余数是cur,cur变成余数0,至少要a次
// 我们想知道 : (哪个余数b + add) % m == cur
// 比如,add=10的时候,cur==5的时候
// 我们想知道 : (哪个余数b + 10) % 7 == 5
// 因为10 % 7 = 3
// 所以其实我们在求 : 哪个余数b + 3 == 5
// 显然b = 5 - 3 = cur - (add % m) = 2
// 再比如,add=10的时候,cur==2的时候
// 我们想知道 : (哪个余数b + 10) % 7 == 2
// 因为10 % 7 = 3
// 所以其实我们在求 : 哪个余数b + 3 == 2
// 这明显是不对的,
// 所以其实我们在求 : 哪个余数b + 3 == 2 + m == 9
// 也就是b,通过加了add % m,来到了m + cur,多转了一圈
// b = 9 - 3 = cur - (add % m) + m = 6
// 也就是说,b = cur - (add % m),
// 如果不小于0,那就是这个b,是我们要找的余数
// 如果小于0,那就是b+m,是我们要找的余数
let mut from: i32 = cur - (add % m as i64) as i32;
if from < 0 {
from += m;
}
// 这个余数我们终于找到了,因为cur变成余数0,需要a次
// 所以这个余数变成余数0,需要a+1次
// 当然前提是这个余数,之前宽度优先遍历的时候,没遇到过
if !visited[from as usize] {
visited[from as usize] = true;
map[from as usize] = map[cur as usize] + 1;
queue[r as usize] = from;
r += 1;
}
add *= 10;
}
}
} fn get_min<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a < b {
a
} else {
b
}
}

代码用solidity编写。代码如下:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17; contract Hello{
function main() public pure returns (int32[] memory){
int32 n = 5;
int32 m = 11;
int32[] memory arr = new int32[](5);
arr[0] = 1;
arr[1] = 3;
arr[2] = 5;
arr[3] = 7;
arr[4] = 9;
int32[] memory ans = times(n,m,arr);
return ans;
} function times(int32 n,int32 m,int32[] memory arr) public pure returns (int32[] memory){
// map[i] : i这个余数变成余数0,需要至少操作几次?
uint mm=uint(uint32(m));
int32[] memory map = new int32[](mm);
bfs(m, map);
uint nn=uint(uint32(n));
int32[] memory ans = new int32[](nn);
for (uint i = 0; i < nn; i++) {
int32 num = arr[i];
int32 minTimes = 2147483647;
if (num < m) {
minTimes = map[uint(uint32(num))];
} else {
for (int64 add = 1; add <= 1000000000; add *= 10) {
int32 mod = int32((int64(num) + add) % int64(m));
minTimes = getMin(minTimes, map[uint(uint32(mod))] + 1);
}
}
ans[i] = minTimes;
}
return ans;
} function getMin(int32 a,int32 b) public pure returns (int32){
if(a<b){
return a;
}else{
return b;
}
} function bfs(int32 m,int32[] memory map) public pure{
uint mm=uint(uint32(m));
bool[] memory visited = new bool[](mm);
visited[0]=true;
int32[] memory queue = new int32[](mm);
int32 l = 0;
int32 r = 1;
// map[0] == 0
// 表示余数0变成余数0,需要至少0次
// 0进队列了, queue[0] = 0
// 0算访问过了,visited[0] = true
while(l<r){
// 当前弹出的余数是cur
int32 cur = queue[uint(uint32(l))];
l++;
// 能加的数字,从1枚举到10^9
for(int64 add = 1;add<=1000000000;add*=10){
// 比如,m == 7
// 当前余数是cur,cur变成余数0,至少要a次
// 我们想知道 : (哪个余数b + add) % m == cur
// 比如,add=10的时候,cur==5的时候
// 我们想知道 : (哪个余数b + 10) % 7 == 5
// 因为10 % 7 = 3
// 所以其实我们在求 : 哪个余数b + 3 == 5
// 显然b = 5 - 3 = cur - (add % m) = 2
// 再比如,add=10的时候,cur==2的时候
// 我们想知道 : (哪个余数b + 10) % 7 == 2
// 因为10 % 7 = 3
// 所以其实我们在求 : 哪个余数b + 3 == 2
// 这明显是不对的,
// 所以其实我们在求 : 哪个余数b + 3 == 2 + m == 9
// 也就是b,通过加了add % m,来到了m + cur,多转了一圈
// b = 9 - 3 = cur - (add % m) + m = 6
// 也就是说,b = cur - (add % m),
// 如果不小于0,那就是这个b,是我们要找的余数
// 如果小于0,那就是b+m,是我们要找的余数
int32 from = cur - int32(add%int64(m));
if (from < 0) {
from += m;
}
// 这个余数我们终于找到了,因为cur变成余数0,需要a次
// 所以这个余数变成余数0,需要a+1次
// 当然前提是这个余数,之前宽度优先遍历的时候,没遇到过
if (!visited[uint(uint32(from))]) {
visited[uint(uint32(from))] = true;
map[uint(uint32(from))] = map[uint(uint32(cur))] + 1;
queue[uint(uint32(r))] = from;
r++;
}
}
}
} }


2023-01-02:某天,小美在玩一款游戏,游戏开始时,有n台机器, 每台机器都有一个能量水平,分别为a1、a2、…、an, 小美每次操作可以选其中的一台机器,假设选的是第i台, 那小美可以将其变成的更多相关文章

  1. 2017-5-14 湘潭市赛 Partial Sum 给n个数,每次操作选择一个L,一个R,表示区间左右端点,该操作产生的贡献为[L+1,R]的和的绝对值-C。 0<=L<R<=n; 如果选过L,R这两个位置,那么以后选择的L,R都不可以再选择这两个位置。最多操作m次,求可以获得的 最大贡献和。

    Partial Sum Accepted : Submit : Time Limit : MS Memory Limit : KB Partial Sum Bobo has a integer seq ...

  2. linux下生成00 01 02..99的这些数

    [root@localhost ~]# seq -s " " -w 9901 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 ...

  3. hdu5795 A Simple Nim 求nim求法,打表找sg值规律 给定n堆石子,每堆有若干石子,两个人轮流操作,每次操作可以选择任意一堆取走任意个石子(不可以为空) 或者选择一堆,把它分成三堆,每堆不为空。求先手必胜,还是后手必胜。

    /** 题目:A Simple Nim 链接:http://acm.hdu.edu.cn/showproblem.php?pid=5795 题意:给定n堆石子,每堆有若干石子,两个人轮流操作,每次操作 ...

  4. Codeforces Round #304 (Div. 2) B. Soldier and Badges【思维/给你一个序列,每次操作你可以对一个元素加1,问最少经过多少次操作,才能使所有元素互不相同】

    B. Soldier and Badges time limit per test 3 seconds memory limit per test 256 megabytes input standa ...

  5. 2023 01 19 HW

    2023 01 19 HW Okay, then let's start.  Okay. Maybe Karina, we start with the C2 design freeze. Yeah, ...

  6. Codeforces Round #191 (Div. 2) A. Flipping Game【*枚举/DP/每次操作可将区间[i,j](1=<i<=j<=n)内牌的状态翻转(即0变1,1变0),求一次翻转操作后,1的个数尽量多】

    A. Flipping Game     time limit per test 1 second memory limit per test 256 megabytes input standard ...

  7. ICML论文|阿尔法狗CTO讲座: AI如何用新型强化学习玩转围棋扑克游戏

    今年8月,Demis Hassabis等人工智能技术先驱们将来到雷锋网“人工智能与机器人创新大会”.在此,我们为大家分享David Silver的论文<不完美信息游戏中的深度强化学习自我对战&g ...

  8. DOM对象本身也是一个js对象,所以严格来说,并不是操作这个对象慢,而是说操作了这个对象后,会触发一些浏览器行为(转)

    一直都听说DOM很慢,要尽量少的去操作DOM,于是就想进一步去探究下为什么大家都会这样说,在网上学习了一些资料,这边整理出来. 首先,DOM对象本身也是一个js对象,所以严格来说,并不是操作这个对象慢 ...

  9. 用python实现自动玩21点小游戏

    1. 背景 前段时间发现一个论坛上(https://npupt.com/blackjack.php)有21点小游戏. 这个21点小游戏的规则是每个人开局都会获得随机点数,如果觉得点数小,可以继续摸牌. ...

  10. 【jQuery】复选框的全选、反选,推断哪些复选框被选中

    本文与<[JavaScript]复选框的全选.反选.推断哪些复选框被选中>(点击打开链接)为姊妹篇,把里面内容再与jQuery框架中实现一次,相同做到例如以下的效果: 布局还是相同的布局, ...

随机推荐

  1. 随笔:for in 和 for of的区别

    百度前端面试题:for in 和 for of的区别详解以及为for in的输出顺序 - 知乎 以该页面为例,我稍微总结一点东西: 在这⾥我们把对象中的数字属性称为 「排序属性」,在V8中被称为 el ...

  2. 2019年居然还出版了一本ASP学习的书籍

    ASP+Dreamweaver动态网站开发(第2版)孙更新,宾晟,李晓娜 著 内容简介 <ASP+Dreamweaver动态网站开发(第2版)>详细介绍了ASP的脚本语言基础.ASP的相关 ...

  3. pytorch CrossEntropyLoss() 默认转换one-hot编码

    import torchpredict = torch.randn((4,3))predict = torch.nn.functional.softmax(predict,dim = 1)target ...

  4. IDEA如何使用Maven不通过模板创建javaWeb项目

    IDEA如何使用Maven不通过模板创建javaWeb项目 1.创建项目 进入IDEA,点击"项目">"新建项目",填写项目信息,最后点击"创建 ...

  5. DVWA-XSS (Stored) 存储型XSS

    存储型XSS,顾名思义,就是会传入数据库,长久的使用,常见为留言板,用户信息资料. LOW 审计源码 <?php // 是否提交 btnSign if( isset( $_POST[ 'btnS ...

  6. Android笔记--修改Device File Explorer的文件打开方式

    在首次打开该文件时,不小心选错了打开方式,导致以后每次打开也是同样的打开方式,也不会弹出第一次那样的打开方式的选择弹窗 在这里提供修改文件的默认打开方式的方法: 首先通过File->settin ...

  7. Java笔记第十一弹

    TCP通信程序 TCP发送数据 //需要进行三次握手 import java.io.*; public class Main{ public static void main(String[] arg ...

  8. GCC编译器编译过程

    GCC编译器编译过程 #生成test可执行文件 g++ test.cpp -o test 其实,上述命令可以分解为以下几个步骤 1. 预处理-Pre-Processing # -E 选择指示编译器仅对 ...

  9. Linux & 标准C语言学习 <DAY6>

    一.数组     什么是数组:变量的组合,是一种批量定义相同类型变量的方式     定义:  类型名 数组名[数量];             int arr[5];             注意:数 ...

  10. 如何使用Mutex确保并发程序的正确性

    1. 简介 本文的主要内容是介绍Go中Mutex并发原语.包含Mutex的基本使用,使用的注意事项以及一些实践建议. 2. 基本使用 2.1 基本定义 Mutex是Go语言中的一种同步原语,全称为Mu ...