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框架中实现一次,相同做到例如以下的效果: 布局还是相同的布局, ...
随机推荐
- arcengine标注转注记
只是将在arcmap中添加注记的方式模拟了一遍,因此,首先显示标注(Label),而后将其转换为注记(Annotation)(Convert Label To Annotation) /******* ...
- 【LuckyFrame研究】环境准备
LuckyFrame官方使用手册:http://www.luckyframe.cn/book/yhsc/syschyy-24.html LuckyFrame在码云平台或是GitHub上都是分成二个项目 ...
- 基本的dns命令
打开cmd的方式 win+r 键 输入cmd 管理员方式运行 打开桌面 命令提示符 盘符切换 直接输入要切换的盘 查看当前目录下所有文件 dir 切换目录 cd /d 跨盘 ...
- centos7下安装Node.js MongoDB Nginx
一.Node.js 方法1(笔者采用).如果对Node.js环境有比较高的要求,建议选择源码安装的方式进行安装,通过wget命令下载Node.js官网上的tar.gz文件包到centos服务器上,进 ...
- 基于Mindspore2.0的GPT2预训练模型迁移教程
摘要: 这篇文章主要目的是为了让大家能够清楚如何用MindSpore2.0来进行模型的迁移. 本文分享自华为云社区<MindNLP-基于Mindspore2.0的GPT2预训练模型迁移教程> ...
- DVWA-Weak Session IDs(弱会话ID) 不安全的会话
在登录服务器之后,服务器会返回给用户一个会话(session),这个会话只会存在一段时间,拥有这个会话下次登录就不用输入密码就可以登录到网站,如果返回的这个会话很弱,容易被猜解到,就很不安全,照成会话 ...
- WinHex恢复分区
情景再现:可能在某一天,打开电脑时发现只剩C盘,剩下的盘找不到了,那么要如何恢复呢? 创建虚拟硬盘方便我们做实验 右键计算机 -> 管理 -> 磁盘管理右键 -> 创建VHD虚拟硬盘 ...
- windows2003 的安装以及安装时遇到的问题
windows2003 的安装以及安装时遇到的问题 简介:Windows Server 2003是微软于2003年3月28日发布的基于Windows XP/NT5.1开发的服务器操作系统,并在同年4月 ...
- 看了还不懂b+tree的本质就来打我
看了还不懂b+tree的本质就来打我 大家好,我是蓝胖子. 今天我们来看看b+tree这种数据结构,我们知道数据库的索引就是由b+tree实现,那么这种结构究竟为什么适合磁盘呢,它又有哪些缺点呢? 我 ...
- Python--基本知识认知及应用
字面量 概念:被写下来的固定的值(既包括print里面的值,也包括直接写到编程页面的值) 在Python中,常用的有六种值的类型:数字.字符串.列表.元组.集合以及字典: Python中,被双引号包围 ...