严肃古板的秩序(DFS)

文章描述了一个编程题目,要求解决含有问号的运算式问题,其中#是一个自定义运算符表示幂模运算。程序使用深度优先搜索策略,通过尝试所有可能的加、减、#替换方案来寻找等式成立的解。在处理大整数时需要注意使用__int128类型以避免溢出。
摘要由CSDN通过智能技术生成

G-严肃古板的秩序_2023牛客寒假算法基础集训营3 (nowcoder.com)

题目描述
小红拿到了一个运算式,其中有一些地方可以填入+'、"'、#(不允许添加括号)。问最终是否可以使得等式成立。若可以,输出任意合法解。否则输出-1。
其中+和-代表四则运算的加法或者减法,'#符号是小红发明的新运算符号: a#b为a的a次方对b取模。例如3#5=33 mod 5=2。"#符号的运算优先级和加减法是相同的(从左到右进行运算)。
在本题中,我们定义a#b当且仅当a和b都是正整数时是有意义的。
输入描述:
一个字符串,该字符串仅包含阿拉伯数字和问号、等号的字符串。保证字符串满足以下性质:
1.字符串仅由阿拉伯数字、'?'和'='组成,第一个字符保证是阿拉伯数字,不存在两个相邻的'?'字符。
⒉.保证有且仅有一个'='字符,'='字符保证不是字符串最后一个字符,'='的左边相邻和右边相邻的一定是阿拉伯数字,且'='右边所有字符均为阿拉伯数字。
3 .所有阿拉伯数字表示的数均为不超过10°的非负整数,若该数为正整数,则保证不包含前导零。4.'?'的数量不超过12个。
输出描述:
如果存在合法解,请输出一个字符串,代表最终的运算式。否则输出-1。
请务必保证,你输出的字符串将所有的'?'修改成了'+'、'-'或者'#',且未修改阿拉伯数字和等号。不得添加或删除新字符。
示例1
输入
复制
2?1?2?2=3

输出
复制
2-1#2+2=3
说明
该答案并不是唯一的。
示例2
输入
复制
5?2=2
输出
复制
-1

题解:

题意没什么好说的,直接暴力搜索考虑每一种情况即可,唯一有点坑的是#操作是会爆long long所以要用__int128,改了半天没发现哪错(QAQ),以后注意如果出现有1e9*1e9的情况要开__int128

下面是看大佬的代码,写的非常简洁,to_string应用

#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<vector>
#include<stack>
#include<cstdio>
#include<string>
#include<cstdio>
#include<cmath>
#include<map>
#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N = 5e5 + 10;
int q[10005];
int it,k;
int res;
//int pow(int a,int p,int m)
//{
//	int ans = 1;
//	while(p)
//	{
//		if(p&1)
//		ans = ans*a%m;
//		a=a*a%m;
//		p >>=1;
//	}
//	return ans;
//}
__int128 ksm(__int128 a,__int128 p,__int128 M){
    __int128 res=1;
    while(p){
        if(p&1){res=res*a%M;}
        a=a*a%M;p>>=1;
    }
    return res;
}
void dfs(int dep,int w,string s)
{
	if(dep == it)
	{
		if(w == res)
		{
			cout <<s<<"="<<res;
			exit(0); 
		}
		return ;
	}
	string s1;
	s1 = s+"+"+to_string(q[dep+1]);
	dfs(dep+1,w+q[dep+1],s1);
	s1 = s+"-"+to_string(q[dep+1]);
	dfs(dep+1,w-q[dep+1],s1);
	if(w > 0&&q[dep]>0)
	{
		s1 = s+"#"+to_string(q[dep+1]);
		dfs(dep+1,ksm(w,w,q[dep+1]),s1);
	}
}
void solve()
{
	string s;
	cin >> s;
	for(auto i:s)
	{
		if(i == '?'||i == '=')
		{
			q[++it] = k;k = 0;
		}
		else
		{
			k = k*10 + i - '0';
		}
	}
	res = k;
	dfs(1,q[1],to_string(q[1]));
	cout<<"-1";
}


signed main()
{
//	ios::sync_with_stdio(0);
//	cin.tie(0);
//	cout.tie(0);
	int t = 1;
//	cin >> t;
	while(t--)
	{

		solve();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值