题目链接
题目大意: 定义一种不进位乘法和加法,给出n让你求出a使得a*a=n
先看定义的不进位的乘法和加法。
看下这个图理解一下,就是每一位的乘法不进位,然后每一位的加法也不进位。
通过 a ∗ a = n a*a=n a∗a=n我们其实可以知道如果 a a a的位数为 x x x那么 n n n的位数应该是 2 ∗ x − 1 = m 2*x-1=m 2∗x−1=m, m m m为 n n n的位数。所以我们可以通过 n n n的位数得到 a a a的位数,也可以通过是否是奇数判断是否可能有解。
我们可以通过固定的位数来判断对应的结果对应的位数。(从后从前都一样)
先从后看,好理解点。
还用上面的例子:1234如果我们确定后两位34那么我们就可以直接算出最终结果的后两位。因为前两位对结果的后两位不做贡献。我们就可以每次判断一下。看看当前位是否可以填上对应的数,可以我们再继续往前填。最后一定要全体判断一下就是判 n n n的位数是否全部对应。这样不一定保证结果最小。
如果我们从前往后填充就可以得到最小值。
#include <map>
#include <queue>
#include <string>
#include<iostream>
#include<stdio.h>
#include<string.h>
#include <algorithm>
#include <math.h>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
typedef pair<ll,ll> pii;
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define mem(a,x) memset(a,x,sizeof(a))
#define debug(x) cout << #x << ": " << x << endl;
#define rep(i,n) for(int i=0;i<(n);++i)
#define repi(i,a,b) for(int i=int(a);i<=(b);++i)
#define repr(i,b,a) for(int i=int(b);i>=(a);--i)
const int maxn=2e6+10;
#define inf 0x3f3f3f3f
#define sf scanf
#define pf printf
const int mod=10000;
const int MOD=1e9+7;
inline int read() {
int x=0;
bool t=false;
char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
vector<ll> m1;
vector<ll> m2;
priority_queue<ll, vector<ll>, greater<ll> > mn; //上 小根堆 小到大
priority_queue<ll, vector<ll>, less<ll> > mx; //下 大根堆 大到小
map<ll,ll>mp;
ll n,m,p;
ll ans=1e18;
ll dis[maxn],vis[maxn];
ll a[maxn],b[maxn],c[maxn];
ll cnt,flag;
bool check(ll num) {
for(int i=0; i<=60; i++) c[i]=0;
for(int i=1; i<=num; i++) {
for(int j=1; j<=num; j++) {
c[i+j-1]=(c[i+j-1]+b[i]*b[j])%10;
}
}
for(int i=1; i<=num; i++) {
if(c[i]!=a[i]) return 0;
}
return 1;
}
void dfs(ll num) {
if(num==n+1) {
if(check(n+n-1)) {
ll p=0;
for(int i=n; i>=1; i--) {
p=p*10+b[i];
}
ans=min(ans,p);
flag=1;
}
return ;
}
for(int i=0; i<=9; i++) {
///数字
if(num==n&&i==0) continue;
b[num]=i;
if(check(num)) {
dfs(num+1);
}
b[num]=0;
}
}
int main() {
string str;
cin>>str;
ll len=str.size();
if((len+1)%2==1) puts("-1");
else {
for(int i=len,j=0; i>=1; i--,j++) {
a[i]=str[j]-'0';
}
n=(len+1)/2;///数位
dfs(1);
if(!flag) puts("-1");
else printf("%lld\n",ans);
}
return 0;
}