2022-04-25每日刷题打卡
代码源——每日一题
倒数第n个字符串 - 题目 - Daimayuan Online Judge
给定一个完全由小写英文字母组成的字符串等差递增序列,该序列中的每个字符串的长度固定为 L,从 L 个 a 开始,以 1 为步长递增。例如当 L 为 3 时,序列为 aaa,aab,aac,…,aaz,aba,abb,…,abz,…,zzz。这个序列的倒数第 2 个字符串就是 zzy。对于任意给定的 L,本题要求你给出对应序列倒数第 N 个字符串。
输入格式
输入在一行中给出两个正整数 L (2≤L≤6)和 N( N≤10^5).
输出格式
在一行中输出对应序列倒数第 N 个字符串。题目保证这个字符串是存在的。
样例输入
6 789
样例输出
zzzyvr
这题其实和进制转化差不多,把一个数转化成26进制的数,0~25对于26个字母。
但是直接转进制是有问题的,因为前置条件有两种,一种是在他给的长度为基础上算,比如这里给的长度L是6,那就是以aaaaaa的基础来算,第二点他给的是倒数的顺序而不是正数。
其实很好办,既然是倒数,我们直接求出最末尾一位的字符串转化成10进制的样子,比如这里长度L是6,最后一位应该是zzzzzz,这是倒数第1个字符串,然后我们要算倒数第N,就用这个数减去N+1即可。再用得到的数通过进制转换求出字符串。
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#define endl '\n';
typedef long long ll;
typedef pair<ll, ll>PII;
const int N = 1e6 + 50;
int main()
{
int l, n;
cin >> l >> n;
ll ans = pow(26, l);
ll res = ans - n;
string s;
if (res == 0)
{
for (int i = 0; i < l; i++)s += 'a';
}
else
{
while (res)
{
s = (char)(res % 26 + 'a') + s;
res /= 26;
}
}
cout << s << endl;
return 0;
}
CodeForces
Problem - 1661B. Getting Zero
Suppose you have an integer v. In one operation, you can:
either set v=(v+1)mod32768
or set v=(2⋅v)mod32768.
You are given n integers a1,a2,…,an. What is the minimum number of operations you need to make each ai equal to 0?
Input
The first line contains the single integer n (1≤n≤32768) — the number of integers.
The second line contains n integers a1,a2,…,an (0≤ai<32768).
Output
Print n integers. The i-th integer should be equal to the minimum number of operations required to make ai equal to 0.
Example
input
4
19 32764 10240 49
output
14 4 4 15
Note
Let’s consider each ai:
a1=19. You can, firstly, increase it by one to get 20 and then multiply it by two 13 times. You’ll get 0 in 1+13=14 steps.
a2=32764. You can increase it by one 4 times: 32764→32765→32766→32767→0.
a3=10240. You can multiply it by two 4 times: 10240→20480→8192→16384→0.
a4=49. You can multiply it by two 15 times.
这题是说,给你n个数,你可以对一个数进行两种操作,一个是把数+1后%32768,一个是把数*2后%32768,问你经过多少步操作可以把一个数变成0。
首先我们已经可以看出了,想把一个数变成0,相当于把这个数变成32768的倍数,然后一个热知识:2^15==32768。也就是说,只要你这个数不是0,那么我们最多15步就可以把你变成0,只要选操作2选15次就行。然后现在有个问题,如果混上了操作1,那最简能是多少步呢?这里我们可以依靠枚举来做,因为最多进行15次操作就可以把一个数变成0,我们枚举这个数从1加到15,加操作后就逐步算*2的操作,要是能在两者操作数相加等于15前把这个数变成0,我们就维护一下这个操作数,如果等于15了还没变0,我们也没必要继续算下去了,这样我们就可以在时间复杂度O(15n)的情况下算出所有数的操作数.
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#define endl '\n';
typedef long long ll;
typedef pair<ll, ll>PII;
const int N = 1e6 + 50;
int main()
{
int n;
cin >> n;
vector<int>v(n), p(16);
p[0] = 1;
for (int i = 1; i <= 15; i++)
{
p[i] = p[i - 1] * 2;
}
for (int i = 0; i < n; i++)cin >> v[i];
for (int i = 0; i < n; i++)
{
if (v[i] == 0)
{
cout << 0 << " ";
continue;
}
int res = 15;
for (int j = 0; j <= 15; j++)
{
int ans = v[i] + j;
for (int k = 0; k <= 15 - j; k++)
{
if (ans * p[k] % 32768 == 0)
{
res = min(res, j + k);
break;
}
}
}
cout << res << " ";
}
return 0;
}