​题目链接​

2021年度训练联盟热身训练赛第一场 C.New Math_#include


2021年度训练联盟热身训练赛第一场 C.New Math_#define_02


2021年度训练联盟热身训练赛第一场 C.New Math_#define_03


2021年度训练联盟热身训练赛第一场 C.New Math_#define_04


题目大意: 定义一种不进位乘法和加法,给出n让你求出a使得a*a=n

先看定义的不进位的乘法和加法。

2021年度训练联盟热身训练赛第一场 C.New Math_i++_05


看下这个图理解一下,就是每一位的乘法不进位,然后每一位的加法也不进位。

通过2021年度训练联盟热身训练赛第一场 C.New Math_#define_06我们其实可以知道如果2021年度训练联盟热身训练赛第一场 C.New Math_#include_07的位数为2021年度训练联盟热身训练赛第一场 C.New Math_#include_08那么2021年度训练联盟热身训练赛第一场 C.New Math_#include_09的位数应该是2021年度训练联盟热身训练赛第一场 C.New Math_i++_102021年度训练联盟热身训练赛第一场 C.New Math_i++_112021年度训练联盟热身训练赛第一场 C.New Math_#include_09的位数。所以我们可以通过2021年度训练联盟热身训练赛第一场 C.New Math_#include_09的位数得到2021年度训练联盟热身训练赛第一场 C.New Math_#include_07的位数,也可以通过是否是奇数判断是否可能有解。

我们可以通过固定的位数来判断对应的结果对应的位数。(从后从前都一样)

先从后看,好理解点。

还用上面的例子:1234如果我们确定后两位34那么我们就可以直接算出最终结果的后两位。因为前两位对结果的后两位不做贡献。我们就可以每次判断一下。看看当前位是否可以填上对应的数,可以我们再继续往前填。最后一定要全体判断一下就是判2021年度训练联盟热身训练赛第一场 C.New Math_#include_09的位数是否全部对应。这样不一定保证结果最小。

如果我们从前往后填充就可以得到最小值。

#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
#define
#define
#define
#define
#define
const int maxn=2e6+10;
#define
#define
#define
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;
}