TopCoder SRM 625 Incrementing Sequence 题解

本题就是给出一个数k和一个数组,包括N个元素,通过每次增加数组中的一个数的操作,最后需要得到1 - N的一个序列,不用排序。

可以从暴力法入手,然后优化。

这里利用hash表进行优化,最终得到时间效率是O(n*n)的算法,而且常数项应该很低,速度还挺快的。

思路:

1 如果数组A[i]在1 -N 范围内,就利用bool B[]记录,这个数已经找到了;

2 如果A[i]的值之前已经找到了,那么就增加k操作,得到新的值A[i]+k,看这个值是否找到了,如果没找到,就使用B记录,如果之前已经找到了,那么就继续重复增加k的操作。

3 如果最后A[i]+k大于N了,那么就可以返回IMPOSIBLE了,因为这样不可能得到要求的数列了。

本算法的缺点是需要额外O(n)的bool空间,不过一般算法会通过sort之后处理也需要O(lgn)的int空间了,所以空间效率其实也差不多。

而本算法的优点是:不需要排序,不需要做模运算,常数项应该低点,运行速度快。

#include <vector>
#include <string>
using namespace std;

class IncrementingSequence
{
public:
	string canItBeDone(int k, vector<int> &A)
	{
		int N = (int)A.size();
		vector<bool> B(N+1);
		for (int i = 0; i < N; i++)
		{
			if (A[i] > N) return "IMPOSSIBLE";
			while (A[i] <= 0 || B[A[i]])
			{
				A[i] += k;
				if (A[i] > N) return "IMPOSSIBLE";
			}
			B[A[i]] = true;//不要错写成B[i]
		}
		for (int i = 1; i <= N; i++)	//别漏这个循环判断
		{
			if (!B[i]) return "IMPOSSIBLE";
		}
		return "POSSIBLE";
	}
};

附一道250分的水题,需要找a*b +c = y,给出y找到a,b,c其中a, b, c 不能等于0, 或者1

#include <vector>
#include <math.h>
using namespace std;

class AddMultiply
{
public:
	vector<int> makeExpression(int y)
	{
		vector<int> vx(3);
		vx[0] = -1; vx[1] = 2;
		vx[2] = y - vx[0] * vx[1];
		return vx;
	}
};

当然,如果还有额外的限制,那么本算法不是完善的,不过这里不错的思路是先找好难的部分,乘法部分,然后找加数就容易了。

TopCoder SRM 625 Incrementing Sequence 题解,布布扣,bubuko.com

时间: 2024-10-23 19:06:27

TopCoder SRM 625 Incrementing Sequence 题解的相关文章

topcoder SRM 625 DIV2 AddMultiply

由于题目告诉肯定至少存在一种解, 故只需要根据条件遍历一下, vector <int> makeExpression(int y) { vector<int> res; for(int i = -1000; i <=1000; ++ i){ for(int j = -1000; j <= 1000; ++ j){ if(i!=0 && i!=1 && j!=0&& j!=1 ){ int k = y-i*j; if(k&g

topcoder srm: NumbersChallenge

用bit mask来做枚举还挺方便的 这个大概是给你一个vector<int> array,求出这个array里任意几个元素加和所不能得到最小的整数. 元素个数最大20个,每个元素不超过100000 比如[1,2,4],那么就应该返回8. (因为3=1+1, 5=1+4等等) 所以枚举这个array的所有子集求和,之后从1开始查看哪个数没有命中然后返回就好. tc上给出的题解如下: static const int MAX = 100000 * 20 + 1; bool poss[MAX];

POJ 1019 Number Sequence 题解

这又是一道看似简单,实际挺困难的题目. 本来想做道基础题消遣一下的,没想到反被消遣了-_-|||. 看个人的基础吧,对于数学好的会简单点,但是由于情况太多,需要都考虑全,故此难度应该在4星以上了. 我这里使用的方法就是直接打表,然后直接模拟,利用打表去掉一大段数据,剩下数据量十分小了,故此可以直接模拟. 打表是为了计算前面的周期数,把周期数直接去掉. 主要难点是后面10位数以上的数有2位, 3位,4位等情况要考虑.- 下面使用getNewNums一个函数解决了,想通了,就几行代码,还不用难理解的

Topcoder SRM 643 Div1 250&lt;peter_pan&gt;

Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*......*pn,我们假设p0,p1,...,pn是单调不降的,那么v里存储的是下标为偶数 的N的质因数p0,p2,p4,...,p(2k).现在要求写一个程序,返回一个vector<long long>ans; ans里存储的是p0,p1,p2,...,pn. Limits Time Limit(m

TopCoder SRM 634 Div.2[ABC]

TopCoder SRM 634 Div.2[ABC] ACM 题目地址: TopCoder SRM 634 赛后做的,感觉现场肯定做不出来Orz,简直不能多说. Level One-MountainRanges[水题] 题意: 问序列中有几个完全大于旁边的峰. 分析: 傻逼题,不多说. 代码: /* * Author: illuz <iilluzen[at]gmail.com> * File: one.cpp * Create Date: 2014-09-26 21:01:23 * Desc

TopCoder SRM 628 DIV 2

250-point problem Problem Statement    Janusz is learning how to play chess. He is using the standard chessboard with 8 rows and 8 columns. Both the rows and the columns are numbered 0 through 7. Thus, we can describe each cell using its two coordina

topcoder SRM 618 DIV2 WritingWords

只需要对word遍历一遍即可 int write(string word) { int cnt = 0; for(int i = 0 ; i < word.length(); ++ i){ cnt+=word[i]-'A'+1; } return cnt; } topcoder SRM 618 DIV2 WritingWords,布布扣,bubuko.com

topcoder SRM 618 DIV2 MovingRooksDiv2

一开始Y1,Y2两个参数看不懂,再看一遍题目后才知道,vector<int>索引代表是行数,值代表的是列 此题数据量不大,直接深度搜索即可 注意这里深度搜索的访问标识不是以前的索引和元素,而是一个交换元素后的整个状态vector<int>,这样可以避免重复元素的搜索 set<vector<int> > visit; bool flag; void dfs(vector<int>& src, vector<int>& d

topcoder SRM 618 DIV2 LongWordsDiv2

此题给出的条件是: (1)word的每个字母都是大写字母(此条件可以忽略,题目给的输入都是大写字母) (2) 相等字符不能连续,即不能出现AABC的连续相同的情况 (3)word中不存在字母组成xyxy的形式,即不存在第一个字符和第3个字符相等同时第2个字符和第4个字符相等的情况 对于第(2)种情况,只需要考虑word[i]!=word[i-1]即可 对于第(3)种情况,用一个4重循环遍历每种可能的情况,然后第一个字符和第3个字符相等同时第2个字符和第4个字符相等,则输出“DisLikes”即可