Educational Codeforces Round 42 (Rated for Div. 2) C. Make a Square (dfs)
C. Make a Square
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given a positive integer n
, written without leading zeroes (for example, the number 04 is incorrect).
In one operation you can delete any digit of the given integer so that the result remains a positive integer without leading zeros.
Determine the minimum number of operations that you need to consistently apply to the given integer n
to make from it the square of some positive integer or report that it is impossible.
An integer x
is the square of some positive integer if and only if x=y2 for some positive integer y
.
Input
The first line contains a single integer n
(1≤n≤2⋅109
). The number is given without leading zeroes.
Output
If it is impossible to make the square of some positive integer from n
, print -1. In the other case, print the minimal number of operations required to do it.
Examples
Input
Copy
8314
Output
Copy
2
Input
Copy
625
Output
Copy
0
Input
Copy
333
Output
Copy
-1
Note
In the first example we should delete from 8314
the digits 3 and 4. After that 8314 become equals to 81, which is the square of the integer 9
.
In the second example the given 625
is the square of the integer 25
, so you should not delete anything.
In the third example it is impossible to make the square from 333
, so the answer is -1.
题意:给一个没有前导0的数n,问进行多少次操作,可以把他变成一个没有前导0的平方数,每次操作删掉该数中的一个数字。
分析:因为n的范围较小,最多只会删9次,所以可以直接用dfs枚举每次删掉的位置,当找到平方数后,更新当前最小的操作数
要注意的是,每次删去之后,要检测是否存在前导0,有前导0的方案是不可行的
在dfs的时候,如果当前的数,已经出现过了,则不需要进行后面的操作,这样就可以用记忆化,优化一点时间。
代码如下:
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <map> #include <vector> #include <cmath> using namespace std; typedef long long LL; #define INF 0x3f3f3f3f LL n,minn; vector<LL>V; vector<LL>V2; map<LL,int>mp; LL sz; void dfs(LL num,vector<LL>V) { if(num==sz)return; LL now=0; for(int i=0;i<V.size();i++) now=now*10+V[i]; if(mp[now])return;//该数出现过,则直接剪掉 mp[now]=1; LL k=sqrt(now); if(k*k==now) { minn=min(num,minn); return; } for(int i=0;i<V.size();i++)//枚举删去的位置 { V2=V; V2.erase(V2.begin()+i); if(V2[0]!=0) dfs(num+1,V2); } } int main() { ios::sync_with_stdio(false); cin>>n; int h=n; while(h>0) { V.push_back(h%10); //将数的每一位都存入到vector里面方便后面的操作 h/=10; } sz=V.size(); reverse(V.begin(),V.end()); minn=INF; dfs(0,V); if(minn>100000000)cout<<"-1"<<endl; else cout<<minn<<endl; return 0; }