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;
}
原文地址:https://www.cnblogs.com/a249189046/p/8821300.html