题意
传送门 LeeCode 1625. 执行操作后字典序最小的字符串
题解
考虑累加,奇数下标元素同时增加 a a a 的整数倍,而处理结果最多只有 10 10 10 种不同的情况,因为对个位数产生影响的只有 a a a 的 0 − 9 0-9 0−9 倍。
考虑轮转,设字符串长度为 n n n,则元素下标变为 i + x × b = j ( m o d n ) , x ∈ Z i+x\times b = j(mod\ n),x\in Z i+x×b=j(mod n),x∈Z,则 j j j 的可能值为 i + x × b + y × n , x ∈ Z , y ∈ Z i+x\times b+y\times n,x\in Z, y\in Z i+x×b+y×n,x∈Z,y∈Z;由裴蜀定理可知,对于任意的整数 x , y x, y x,y, g c d ( a , b ) gcd(a, b) gcd(a,b) 是 ( a x + b y ) (ax + by) (ax+by) 的最小正值;那么 j − i j-i j−i 的最小差值为 g c d ( n , b ) gcd(n,b) gcd(n,b),枚举不同的字符串首元素即可,只有 n / g c d ( n , b ) + 1 n/gcd(n,b)+1 n/gcd(n,b)+1 种可能。
class Solution
{
public:
string findLexSmallestString(string s, int a, int b)
{
vector<int> table(10);
for (int i = 0; i < 10; ++i)
table[i] = a * i;
int n = s.length(), gcd = __gcd(n, b), ub = (gcd & 1) ? 10 : 1;
string str = s + s, res = s;
for (int k = 0; k < n; k += gcd)
{
string tmp = str.substr(k, n);
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j < ub; ++j)
{
string tmp2(tmp);
for (int t = 1; t < n; t += 2)
{
tmp2[t] = (tmp2[t] - '0' + table[i]) % 10 + '0';
}
for (int t = 0; t < n; t += 2)
{
tmp2[t] = (tmp2[t] - '0' + table[j]) % 10 + '0';
}
res = min(res, tmp2);
}
}
}
return res;
}
};