1. 问题描述:
给定一个不含前导 0 的正整数 n。你可以对 n 进行删位操作。每次操作,可以将 n 的任意一位数字删去,但是需要保证每次操作完成后的数字仍然是不含前导 0 的正整数。如果想要使得 n 可以成为某个正整数的平方,那么最少需要对 n 进行多少次操作?
输入格式
第一行包含整数 T,表示共有 T 组测试数据。每组数据占一行,包含一个整数 n。
输出格式
每组数据输出一行结果,表示最少需要的操作次数,如果不可能使 n 变为某个正整数的平方,则输出 −1。
数据范围
前三个测试点满足 1 ≤ n ≤ 10000。
所有测试点满足 1 ≤ T ≤ 10,1 ≤ n ≤ 2 × 10 ^ 9。
输入样例1:
1
8314
输出样例1:
2
输入样例2:
1
625
输出样例2:
0
输入样例3:
1
333
输出样例3:
-1
来源:https://www.acwing.com/problem/content/description/3799/
2. 思路分析:
分析题目可以知道n最多有9位数字,因为需要删除掉某些位所以我们可以选择当前位上的数字也不选当前位上的数字(不选表示删除),也即需要搜索出所有的方案,可以使用dfs来搜索,一个分支表示选择当前的数字,另外一个分支表示不选择当前的数字,这样一定可以枚举出所有的情况,我们可以将枚举出的数字存储到vector或者是列表中,然后从大到小排序,从大的数字开始枚举判断是否是平方数字即可。
3. 代码如下:
import math
from typing import List
class Solution:
# 求解出选还是不选当前位对应的的数字的所有情况
def dfs(self, u: int, nums: List[str], rec: List[int], s: str):
if u == len(nums):
# 筛选掉空串和前导0字符串
if s and s[0] != "0":
rec.append(int(s))
return
# 选择当前位置的元素
self.dfs(u + 1, nums, rec, s + nums[u])
# 不选择当前位置的元素
self.dfs(u + 1, nums, rec, s)
def process(self):
T = int(input())
for i in range(T):
n = int(input())
nums = list()
t = n
# 求解出n的每一位数字将其按照顺序插入到nums中
while t > 0:
nums.insert(0, str(t % 10))
t //= 10
rec = list()
self.dfs(0, nums, rec, "")
# 从大到小排序, 排在前面的肯定是长度比较长的
rec.sort(reverse=True)
flag = 0
for x in rec:
a = int(math.sqrt(x))
if a * a == x:
print(len(str(n)) - len(str(x)))
flag = 1
break
if not flag: print(-1)
if __name__ == "__main__":
Solution().process()