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();
}
}