2021年度训练联盟热身训练赛第一场 —— C

链接: link.

题意:

给你一个数n,求最小的数x使得x的平方等于n,运算过程中只以个位作为有效数字,比如正常情况4×4=16,在这里4×4=6;正常情况17×17=289,在这里17×17=149.
在这里插入图片描述

思路:

首先写一下乘法竖式。
在这里插入图片描述
1、首先可以发现,得到的答案的位数一定是一个奇数,而且是x的位数乘2加1,所以答案位数一定是偶数。那么如果n的位数+1是一个奇数,一定找不到x。
2、再来看能找的情况,我们假设n有p位,那么x就有k = (p+1)/2位,可以发现通过枚举n的最高位(称它为第1位)可以找到符合的a,然后依次向后搜索到n的第k位就可以确定abcd四个数字,也就是x的值,然后再通过余下的几位来验算是否可行。
3、可以发现每一位的值,都是交叉相乘相加后取余,如果第3位,就是1×3,2×2,1×3(这里的1,2,3表示下标)。

注意:

1、因为要找到最小的x,所以从最高位开始搜索,一旦找到直接return。
2、n的位数最多有25位。

代码

#include <bits/stdc++.h>
#define ll long long
#define T int T;scanf("%d", &T);while(T--)
using namespace std;
const int mod = 998244353;
const int maxn = 2e5+10;
string s;
int k;	//x的位数
int a[30];	//存x的每一位
int ok = 0;	//标记是否找到
vector<int> ans;
void dfs(int x){
	if(ok) return;
	if(x>=k){
		int f = 1;
		for(int i = k; i < s.size(); i++){	//验算
			int cnt = 0;
			int p = i-(k-1);
			for(int j = p; j < s.size(); j++){	//交叉相乘相加取余
				cnt = (cnt+(a[j])*(a[k-1-(j-p)]))%10;	
			}
			if(cnt != s[i]-'0'){	
				f = 0;
				break;
			}
		}
		if(f){	//如果验算发现没问题
			for(int i = 0; i < k; i++){
				ans.push_back(a[i]);
				ok = 1;
			}
		}
		return;
	}
	for(int i = 0; i < 10; i++){	
		if(ok) return;
		a[x] = i;	//计算当前这位为i时可不可行
		int cnt = 0;	//值
		for(int j = 0; j <= x; j++){	//交叉相乘相加取余
			// cout << "-> ";
			// cout << a[j] << " " << a[x-j] << endl;
			cnt = (cnt+(a[j])*(a[x-j]))%10;
		}
		// cout << "=== " << x <<" "<<i<< " "  << cnt << endl;
		if(cnt==s[x]-'0'){		//如果可行,继续搜索下一位
			a[x] = i;
			// printf("---> a[%d] = %d\n", x, i);
			dfs(x+1);
		}
	}
}
int main(){
	cin >> s;
	if((s.size()+1)&1){
		cout << -1 << endl;
		return 0;
	}
	k = (s.size()+1)/2;
	dfs(0);
	if(ok) for(auto i : ans) cout << i;
	else cout << -1 << endl;

	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值