2023-01-02:某天,小美在玩一款游戏,游戏开始时,有n台机器, 每台机器都有一个能量水平,分别为a1、a2、…、an, 小美每次操作可以选其中的一台机器,假设选的是第i台, 那小美可以将其变成
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台, 那小美可以将其变成的更多相关文章
- 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 ...
- 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 ...
- hdu5795 A Simple Nim 求nim求法,打表找sg值规律 给定n堆石子,每堆有若干石子,两个人轮流操作,每次操作可以选择任意一堆取走任意个石子(不可以为空) 或者选择一堆,把它分成三堆,每堆不为空。求先手必胜,还是后手必胜。
/** 题目:A Simple Nim 链接:http://acm.hdu.edu.cn/showproblem.php?pid=5795 题意:给定n堆石子,每堆有若干石子,两个人轮流操作,每次操作 ...
- 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 ...
- 2023 01 19 HW
2023 01 19 HW Okay, then let's start. Okay. Maybe Karina, we start with the C2 design freeze. Yeah, ...
- 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 ...
- ICML论文|阿尔法狗CTO讲座: AI如何用新型强化学习玩转围棋扑克游戏
今年8月,Demis Hassabis等人工智能技术先驱们将来到雷锋网“人工智能与机器人创新大会”.在此,我们为大家分享David Silver的论文<不完美信息游戏中的深度强化学习自我对战&g ...
- DOM对象本身也是一个js对象,所以严格来说,并不是操作这个对象慢,而是说操作了这个对象后,会触发一些浏览器行为(转)
一直都听说DOM很慢,要尽量少的去操作DOM,于是就想进一步去探究下为什么大家都会这样说,在网上学习了一些资料,这边整理出来. 首先,DOM对象本身也是一个js对象,所以严格来说,并不是操作这个对象慢 ...
- 用python实现自动玩21点小游戏
1. 背景 前段时间发现一个论坛上(https://npupt.com/blackjack.php)有21点小游戏. 这个21点小游戏的规则是每个人开局都会获得随机点数,如果觉得点数小,可以继续摸牌. ...
- 【jQuery】复选框的全选、反选,推断哪些复选框被选中
本文与<[JavaScript]复选框的全选.反选.推断哪些复选框被选中>(点击打开链接)为姊妹篇,把里面内容再与jQuery框架中实现一次,相同做到例如以下的效果: 布局还是相同的布局, ...
随机推荐
- EL表达式 总结
EL表达式,全称是Expression Language.意为表达式语言.它是Servlet规范中的一部分,是JSP2.0规范加入的内容.其作用是用于在JSP页面中获取数据,从而让我们的JSP脱离ja ...
- 使用ActiveMQ中遇到的端口占用问题
原Linux虚拟机中安装了ActiveMQ,EMQX.后期使用中主要使用EMQX来实现消息服务,停止了ActiveMQ.但是虚拟机挂起之后,长时间未再使用.近期由于有使用ActiveMQ的需要,而临时 ...
- 9. 实现包括前端后台的预约洗狗功能 - 使用Power Automate发送预约邮件 - 使用Power Automate发送带选择按钮(option)的邮件
除了发送普通的电子邮件外,我们还可以选择发送带选项的电子邮件来得到客户的反馈,下面我们就一起来创建带有选择功能的电子邮件吧. 1. 打开我们的Power Portal,在左侧导航栏选择流,点击左上 ...
- windows下使用Wireshark调试chrome浏览器的HTTP/2流量
1.在Wireshark官网(https://www.wireshark.org/#download)下载对应的Wireshark安装包,进行安装 2.增加系统环境变量设置(计算机 -- 右键 -- ...
- 在CentOS中安装和使用nginx
概述 本文简单讲述一下,如何快速将一个内网的Web服务通过nginx提供给外网访问,并且启用HTTPS.例如我们部署了一个kubesphere,地址为192.168.202.151:30880,需要通 ...
- vivo 短视频用户访问体验优化实践
作者:vivo 互联网运维团队- Hu Tao 本文介绍了vivo短视频用户访问体验优化的实践思路,并简单讲解了实践背后的几点原理. 一.背景 我们平时在看抖音快手视频的时候,如果滑动到某个视频画面一 ...
- IO流详解及常用方法
1.1. 什么是IO流 IO流: Input/Output Stream 流: 指的是一串流动的数据, 在数据在流中按照指定的方向进行流动. 实现数据的读取.写入的功能. 1.2. IO流的使用场景 ...
- SpringBoot接入微信JSSDK,看这篇妥妥的
先给猴急的客官上干货代码 GitHub 接入微信JSSDK GitHub地址 Gitee 接入微信JSSDK GitHub地址 前言 事情的起因是因为疫情严重,领导要求做一个专题页,能够尽可能帮助所需 ...
- SimpleAdmin手摸手教学之:项目架构设计2.0
一.说明 在SimpleAdmin1.0版本中,我将整体项目结构分为三大块,分别为架构核心.业务模块和应用服务.随着1.0版本的封版,回去再看我之前的项目架构,也暴露了一些问题,比如在1.0版本中,S ...
- Windows注册表中修改UAC(用户账号控制)及批处理脚
我在windows电脑上安装软件时,或者设置开机启动软件时,会先弹出提示框: 用户账户控制 你要允许此应用对你的设备进行更改吗? 很烦人,我不想每次都提醒.需要关闭"用户账户控制" ...