题解: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;
}
相关推荐
listhi5201 小时前
双目立体视觉中的彩色SAD算法
算法
爱coding的橙子2 小时前
Day87:2.12:leetcode 动态规划8道题,用时3h
算法·leetcode·动态规划
阿猿收手吧!2 小时前
【C++】模块:告别头文件新时代
开发语言·c++
星火开发设计2 小时前
虚析构函数:解决子类对象的内存泄漏
java·开发语言·前端·c++·学习·算法·知识
2501_901147832 小时前
幂函数实现的优化与工程思考笔记
笔记·算法·面试·职场和发展·php
好大的月亮2 小时前
中值法排序及LexoRank排序算法简述
java·算法·排序算法
闻缺陷则喜何志丹2 小时前
【拆位法】P9277 [AGM 2023 资格赛] 反转|普及+
c++·算法·位运算·拆位法
maplewen.2 小时前
C++ 多态原理深入理解
开发语言·c++·面试
tbRNA2 小时前
C++ string类
开发语言·c++