题解:P8035 [COCI 2015/2016 #7] Otpor

题目传送门

题目大意

给出一个由变量名和运算符组成的表达式,计算值。

新定义运算符:- 表示串联,| 表示并联。

运算符计算

·- 表示串联

计算方式: ans=R1​+R2​+⋯+Rk​

·| 表示并联

计算方式: ans=1/(R1​1​+R2​1​+⋯+Rk​1​)

核心思路

我们可以发现,这就是一道套了个新定义皮的表达式计算。

∵ 需要处理嵌套括号,而栈的 后进先出 特性正好匹配括号的嵌套结构。

∴ 可使用 来计算表达式的值。

提示:串并联符号和左括号需要用特殊数字标记,压入栈后再统一计算。

代码

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;
}
相关推荐
To_OC5 小时前
从一次栈溢出报错说起,我把递归彻底扒明白了
javascript·算法·程序员
千纸鹤安安10 小时前
千问Qwen-AgentWorld来了:一个语言模型搞定七大Agent场景,GPT-5.4都输了
算法
七牛开发者13 小时前
MCP 到底是什么?为什么 Agent 都想接上它
算法·aigc·agent
卷无止境18 小时前
C++ 的Eigen 库全解析
c++
卷无止境18 小时前
现代 C++特性大盘点:一门脱胎换骨的老语言
c++·后端
郝学胜_神的一滴19 小时前
CMake 27:缓存变量的特性、语法、类型与实操全解
c++·cmake
kisshyshy19 小时前
从递归到迭代,一文吃透二叉树的核心知识与 JavaScript 实现
javascript·算法·代码规范
To_OC1 天前
LC 49 字母异位词分组:想到哈希表很简单,选对 key 才是精髓
javascript·算法·leetcode