poj 4090:超级备忘录

poj 4090:超级备忘录

题目:

描述

你的朋友Jackson被邀请参加一个叫做“超级备忘录”的电视节目。在这个节目中,参与者需要玩一个记忆游戏。在一开始,主持人会告诉所有参与者一个数列,{A1, A2, ..., An}。接下来,主持人会在数列上做一些操作,操作包括以下几种:

  1. ADD x y D:给子序列{Ax, ..., Ay}统一加上一个数D。例如,在{1, 2, 3, 4, 5}上进行操作"ADD 2 4 1"会得到{1, 3, 4, 5, 5}。
  2. REVERSE x y:将子序列{Ax, ..., Ay}逆序排布。例如,在{1, 2, 3, 4, 5}上进行操作"REVERSE 2 4"会得到{1, 4, 3, 2, 5}。
  3. REVOLVE x y T:将子序列{Ax, ..., Ay}轮换T次。例如,在{1, 2, 3, 4, 5}上进行操作"REVOLVE 2 4 2"会得到{1, 3, 4, 2, 5}。
  4. INSERT x P:在Ax后面插入P。例如,在{1, 2, 3, 4, 5}上进行操作"INSERT 2 4"会得到{1, 2, 4, 3, 4, 5}。
  5. DELETE x:删除Ax。在Ax后面插入P。例如,在{1, 2, 3, 4, 5}上进行操作"DELETE 2"会得到{1, 3, 4, 5}。
  6. MIN x y:查询子序列{Ax, ..., Ay}中的最小值。例如,{1, 2, 3, 4, 5}上执行"MIN 2 4"的正确答案为2。

为了使得节目更加好看,每个参赛人都有机会在觉得困难时打电话请求场外观众的帮助。你的任务是看这个电视节目,然后写一个程序对于每一个询问计算出结果,这样可以使得Jackson在任何时候打电话求助你的时候,你都可以给出正确答案。

输入
第一行包含一个数n (n ≤ 100000)。

接下来n行给出了序列中的数。

接下来一行包含一个数M (M ≤ 100000),描述操作和询问的数量。

接下来M行给出了所有的操作和询问。

解题方案

这里面最有深度的题目就是旋转了,所以分析只有针对旋转的

对一个数组旋转怎么做呢?暴力法可以么,可以,但是很慢

那么我们怎么办?如果实验较多我们会发现有一个规律,我们设 length 为数组长度,需要旋转的次数为 n (0 < n < length )

我们将根据 length 是否能整除 m (= n<(length-n) ? n : length - n )分为两种情况设计算法

但是每一种情况时间复杂度都是 O(length),所以这是比较快的

我们先看能整除的那种情况

length = 6; m = 1; length % m = 0;共有m个大循环

length = 6 ; m = 2; length % m = 0; 共有m个大循环

第二种情况,不能整除

length = 7 ;n = 4 ; m = 3 ;length % m == 1; 这时只用一个大循环就可以。

代码

#include <iostream>
using namespace std;

class intList
{
	int * data;
	int length;
public:
	intList()
	{
		data = NULL;
		length = 0;
	}

	void add( int x,int y,int D )
	{
		for( int i=x;i<=y;i++ )
		{
			data[i-1] += D;
		}
	}

	void reverse( int x,int y )
	{
		for(int i = 0; i < (y-x+1)/2 ; i++)
		{
			int d = data[x+i-1];
			data[x+i-1] = data[y-i-1];
			data[y-i-1] = d;
		}
	}

	void revolve(int x,int y,int T)
	{
		int len = y - x + 1;
		int m = T<(len-T)? T:(len - T);
		T = T % len;
		if( T != 0 )
		if( len % m == 0 )
		{
			for(int i=0;i<m;i++)
			{
				int flag = i;
				int flag_data = data[i+x-1];
				int j = i ;
				while ( (j+T)%len != flag )
				{
					int d = data[(j+T)%len + x-1];
					data[(j+T)%len + x-1] = flag_data ;
					flag_data = d;
					j = (j+T)%len ;
				}
				data[flag+x-1] = flag_data;
			}
		}
		else
		{
			int flag = 0;
			int flag_data = data[flag+x-1];
			int j = 0;

			while( (j+T)%len != flag )
			{
				int d = data[(j+T)%len + x-1] ;
				data[(j+T)%len + x-1] = flag_data ;
				flag_data = d ;
				j = (j+T)%len ;
			}
			data[flag] = flag_data ;
		}
	}

	void insert( int x,int P )
	{
		length++ ;
		int * big_data = new int[ length ];

		for(int i=length-1;i>=x;i--)
			big_data[i] = data[i-1];
		big_data[x-1] = P;
		for(int i=x-2;i>=0;i--)
			big_data[i] = data[i];

		delete [] data;
		data = big_data;
	}

	void delete_x(int x)
	{
		for( int i = x-1;i < length-1 ; i++ )
		{
			data[i] = data[i+1];
		}
		length -- ;
	}

	int min(int x,int y)
	{
		int min = INT_MAX;
		for(int i=x; i<=y; i++)
		{
			if(data[i-1] < min )
				min = data[i-1];
		}
		return min;
	}

	void print_list()
	{
		for( int i=0; i<length; i++ )
		{
			cout<<data[i]<<" ";
		}
		cout<<endl;
	}
};

int main()
{
	intList mylist;

	for(int i=1;i<10;i++)
	mylist.insert(i,i);
	mylist.print_list();

	mylist.insert( 1,4 );
	mylist.add( 1,9,1 );
	mylist.print_list( );

	mylist.delete_x( 3 );
	mylist.print_list( );

	cout<<mylist.min(5,9)<<endl;

	mylist.revolve(1,6,4);
	mylist.print_list( );

	mylist.reverse(1,4);
	mylist.print_list();
	system("pause");
	return 0;
}
时间: 2024-10-15 17:30:02

poj 4090:超级备忘录的相关文章

今日事意见汇总

通过阅读其他人的建议,现总结如下: 1.界面有待改进 2.没有突出自己的特色,没有市场竞争力 3.实现功能过于单一 针对这些问题解决方案如下: 界面会不断进行优化,争取做到简洁美观 关于特色,我们准备在后期加上锁屏提醒功能和语音录入功能. 这个软件我们定位是超级备忘录,力求做到简洁明了

poj水题-3062 超级水题的深层理解——代码简化

题目很简单,要求输入什么样输出什么样.以回车结束 这就是我用的C代码 #include <stdio.h> int main (){char p;for(;gets(&p);)puts(&p);return 0;} 使用了代码简化方案,我简化到了75B.有大神简化到31B,真想看看他们的源代码.我估计他们比我个能够了解语言规则. 这里不得不说一本叫<短码之美>的书.介绍了这道题.但我试过了,没用.可能系统升级了吧,必须要求C99. ,还听说不用#include也行,

poj 1459 Power Network【建立超级源点,超级汇点】

Power Network Time Limit: 2000MS   Memory Limit: 32768K Total Submissions: 25514   Accepted: 13287 Description A power network consists of nodes (power stations, consumers and dispatchers) connected by power transport lines. A node u may be supplied

poj 3308 Paratroopers 最小割 最小点权覆盖

题目链接:http://poj.org/problem?id=3308 题意: 有一个M*N的图,上面的一些点上有伞兵. 可以设置一些枪在每行或者每列上,通过射击,这行或这列的伞兵就会被消灭.每个枪的设置有一个花费,如果设置多个枪,那么花费是设置每个枪的乘积. 问消灭所有伞兵最少的花费是多少. 思路: 每个点的伞兵至少要用那一列或者那一行设置的枪去消灭,那么就可以应用点覆盖的模型.把伞兵看成是一条边,这条边至少要用一个点来覆盖. 而题目中最终花费是所有花费的乘积,那么可以用对数log(x)+lo

图论 500题——主要为hdu/poj/zoj

转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并查集======================================[HDU]1213   How Many Tables   基础并查集★1272   小希的迷宫   基础并查集★1325&&poj1308  Is It A Tree?   基础并查集★1856   More i

OOTV杯超级模式大赛——模式总结

设计模式的学习就要结束了,这么些天,一直徜徉在大鸟和小菜的故事世界之中.那一段段经典的对话,那一个个有趣而又充满知识的经历,真的让自己受益匪浅. 除此之外,那场OOTV杯超级模式大赛,真的很精彩.那么,就让我们随着比赛的脚步,再一次充当观众,一起去回味,再次领略各种模式的魅力所在. 主持人--GOF,首先出现在台前给大家问好.可能有人就会问了,为什么主持人会是她呢?其实,学习了设计模式的同学都知道,GOF来头可不小.下面就让我先给大家对GOF做一个简单介绍吧. GOF,全称Gang ofFour

POJ 2195 &amp; HDU 1533 Going Home(最小费用最大流)

题目链接: POJ:http://poj.org/problem?id=2195 HDU:http://acm.hdu.edu.cn/showproblem.php?pid=1533 Description On a grid map there are n little men and n houses. In each unit time, every little man can move one unit step, either horizontally, or vertically,

POJ 3680 Intervals(费用流+离散化)

题目地址:POJ 3680 这题的建图真心想不出来.建图思维还是不够开阔,不够大胆. 这题要先对坐标进行离散化.可以用左边的点发出一条到右边的点的边,容量为1,费用为负的权值.然后从左往右将依次将相邻的两个点都连起来,权值为0,容量为k,也就是说,如果选了这个区间,就会从费用为负数的边流过去,否则,就是从这个费用为0的边流过去.然后建立一个超级源点与最左边的点相连,权值为0,容量为k,这样就保证了重叠数之多为k,因为增广路上所经过的区间必定是不重合的,而流量只有k,所以满足题意. 代码如下: #

POJ 3436 ACM Computer Factory(网络最大流)

http://poj.org/problem?id=3436 ACM Computer Factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5286   Accepted: 1813   Special Judge Description As you know, all the computers used for ACM contests must be identical, so the particip