题目大意
给出一个由变量名和运算符组成的表达式,计算值。
新定义运算符:- 表示串联,| 表示并联。
运算符计算
·- 表示串联
计算方式: ans=R1+R2+⋯+Rk
·| 表示并联
计算方式: ans=1/(R11+R21+⋯+Rk1)
核心思路
我们可以发现,这就是一道套了个新定义皮的表达式计算。
∵ 需要处理嵌套括号,而栈的 后进先出 特性正好匹配括号的嵌套结构。
∴ 可使用 栈 来计算表达式的值。
提示:串并联符号和左括号需要用特殊数字标记,压入栈后再统一计算。
代码
cpp
#include<bits/stdc++.h>
#define int long long
using namespace std;
vector<int> op1(const vector<int>& a, int n)
{
vector<int> r=a;
for(int i=0;i<2*n;i+=2) swap(r[i],r[i+1]);
return r;
}//相邻两两交换
vector<int> op2(const vector<int>& a, int n)
{
vector<int> r=a;
for(int i=0;i<n;++i) swap(r[i],r[i+n]);
return r;
}//前后两半对应交换
signed main()
{
int n;cin>>n;
vector<int> p(2*n);// p=初始排列数组
for(int i=0;i<2*n;++i)
cin>>p[i];
vector<int> t(2*n);// t=目标有序数组
for(int i=0;i<2*n;++i)
t[i]=i+1;// 初始化目标数组为1~2n
if(p==t)
{
cout<<0<<endl;
return 0;
}//初始已排序
const int M=10000; // 最大模拟步数(避免无限循环)
int m=INT_MAX; // 最小操作次数(初始为无穷大)
vector<int> c=p; // 当前模拟的数组状态
int s=0; // 当前累计操作步数
for(int i=0;i<M/2;++i)
{
c=op1(c,n);
s++;//操作1,步数+1
if(c==t)
{
m=min(m,s);
break;
}//达到目标,更新最小步数并退出
c=op2(c,n);
s++;//操作2,步数+1
if(c==t)
{
m=min(m,s);
break;
}//同上
}//先执行操作2,再交替执行操作1、操作2...
c=p;s=0;//重置
for(int i=0;i<M/2;++i)
{
c=op2(c,n);
s++;//操作2,步数+1
if(c==t)
{
m=min(m,s);
break;
}//同上
c=op1(c,n);
s++;//操作1,步数+1
if(c==t)
{
m=min(m,s);
break;
}//同上
}
if(m!=INT_MAX) cout<<m<<endl;
else cout<<-1<<endl;
return 0;
}