Cheolsoo is a cryptographer in ICPC(International Cryptographic Program Company). Recently, Cheolsoo developed a cryptographic algorithm called ACM(Advanced Cryptographic Method). ACM uses a key to encrypt
a message. The encrypted message is called a cipher text. In ACM, to decrypt a cipher text, the same key used in the encryption should be applied. That is, the encryption key and the decryption key are the same. So, the sender and receiver should
agree on a key before they communicate securely using ACM. Soon after Cheolsoo finished the design of ACM, he asked its analysis on security to Younghee who is a cryptanalyst in ICPC.

Younghee has an interest in breaking cryptosystems. Actually, she developed many attacking methods for well-known cryptographic algorithms. Some cryptographic algorithms have weak keys. When a message is encrypted with a weak key, the message can be
recovered easily without the key from the cipher text. So, weak key should not be used when encrypting a message. After many trials, she found the characteristic of weak keys in ACM. ACM uses a sequence of mutually distinct positive integers (N1N2,..., Nk) as
a key. Younghee found that weak keys in ACM have the following two special patterns:

There are four integers NpNqNrNs(1p < q < r < sk) in
the key such that
(1) Nq > Ns > Np > Nr or Nq < Ns < Np < Nr

For example, the key (10, 30, 60, 40, 20, 50) has the pattern in (1); (_, 30, 60, _, 20, 50). So, the key is a weak key in ACM. But, the key (30, 40, 10, 20, 80, 50, 60, 70) is not weak because it does not have
any pattern in the above.

Now, Younghee wants to find an efficient method to determine, for a given key, whether it is a weak key or not. Write a program that can help Younghee.

Input

The input consists of T test cases. The number of test cases T is given in the first line of the input file. Each test case starts with a line
containing an integer k, the length of a sequence repressenting a key, 4k5,
000. In the next line, k mutually distinct positive integers are given. There is a single space between the integers, and the integers are between 1 and 100,000, both inclusive.

Output

Print exactly one line for each test case. Print `YES' if the sequence is a weak key. Otherwise, print `NO'.

The following shows sample input and output for three test cases.

Sample Input

3
6
10 30 60 40 20 50
8
30 40 10 20 80 50 60 70
4
1 2 20 9

Sample Output

YES
NO
NO

要求找到4个整数Np、Nq、Nr、Ns(1<= p < q < r < s <= k)s.t. Nq > Ns > Np > Nr or Nq < Ns < Np < Nr。

先看第一种情况,下标第二大的,值最大,而下标第三大的,值最小,下标最小和最大的都插在了中间,确定这个要求后,先想到dfs求解,但是考虑到5000这个数量比较大,怕函数进出栈太慢。

直接枚举四个值时间复杂度又太高了,所以只枚举两个,枚举Ns和Np,然后记录找到Nq和Nr。

用了两个标记数组, l[i][j] 表示下标小于j且值比Ni大的数中最小值的位置,r[i][j] 表示下标大于j且值比Ni小的数中最大值的位置。

最后在枚举判断就完成了第一种情况。第二种情况直接把数组翻转,然后在判断一次就行了。

AC代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <string>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <stack>
#include <queue>
#include <bitset>
#include <cassert>
#include <cmath>
#include <functional>

using namespace std;

const int maxn = 5005;
int num[maxn], l[maxn][maxn], r[maxn][maxn];
// l[i][j]表示下标小于j且值比Ni大的数中最小值的位置
// r[i][j]表示下标大于j且值比Ni小的数中最大值的位置
int k;

bool solve()
{
	for (int i = 1; i <= k; i++) {
		l[i][0] = 0;
		for (int j = 1; j < i; j++) { // 枚举Nq和Nr,找Np
			if (num[i] >= num[j]) {
				l[i][j] = l[i][j - 1];
			}
			else if (!l[i][j - 1] || num[j] < num[l[i][j - 1]]) {
				l[i][j] = j;
			}
			else {
				l[i][j] = l[i][j - 1];
			}
		}

	}

	for (int i = 1; i <= k; i++) {
		r[i][k + 1] = 0;
		for (int j = k; j > i; j--) {// 枚举Nq和Nr,找Ns
			if (num[i] <= num[j]) {
				r[i][j] = r[i][j + 1];
			}
			else if (!r[i][j + 1] || num[j] > num[r[i][j + 1]]) {
				r[i][j] = j;
			}
			else {
				r[i][j] = r[i][j + 1];
			}
		}
	}

	//i是q,j是r
	for (int i = 1; i <= k; i++) {
		for (int j = i + 1; j <= k; j++) {
			if (!l[j][i - 1] || !r[i][j + 1] || num[i] <= num[j]) {
				continue;
			}
			int p = l[j][i - 1], s = r[i][j + 1];
			if (num[j] < num[p] && num[p] < num[s] && num[s] < num[i]) {
				return true;
			}
		}
	}
	return false;
}

int main()
{
	ios::sync_with_stdio(false);
	int T;
	cin >> T;
	while (T--) {
		cin >> k;
		for (int i = 1; i <= k; i++) {
			cin >> num[i];
		}

		if (solve()) {
			cout << "YES\n";
		}
		else {
			reverse(num + 1, num + k + 1);
			if (solve()) {
				cout << "YES\n";
			}
			else {
				cout << "NO\n";
			}
		}
	}

	return 0;
}

UVa - 1618 - Weak Key的更多相关文章

  1. UVA - 1618 Weak Key(RMQ算法)

    题目: 给出k个互不相同的证书组成的序列Ni,判断是否存在4个证书Np.Nq.Nr.Ns(1≤p<q<r<s≤k)使得Nq>Ns>Np>Nr或者Nq<Ns&l ...

  2. 【习题 8-16 UVA - 1618】Weak Key

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 枚举N[q]和N[r]的位置 因为N[q]是最大值,且N[r]是最小值. 且它们是中间的两个. 枚举这两个可以做到不重复枚举. 然后 ...

  3. 弱键(Weak Key, ACM/ICPC Seoul 2004, UVa1618)

    I think: 给出k(4≤k≤5000)个互不相同的整数组成的序列Ni,判断是否存在4个整数Np.Nq.Nr和Ns(1≤p<q<r<s≤k),使得Nq>Ns>Np&g ...

  4. 紫书 习题 8-16 UVa 1618 (中途相遇法)

    暴力n的四次方, 然而可以用中途相遇法的思想, 分左边两个数和右边两个数来判断, 最后合起来判断. 一边是n平方logn, 合起来是n平方logn(枚举n平方, 二分logn) (1)两种比较方式是相 ...

  5. UVA1618-Weak Key(RMQ)

    Problem UVA1618-Weak Key Accept: 103  Submit: 588Time Limit: 3000 mSec Problem Description Cheolsoo ...

  6. 多线程爬坑之路-Thread和Runable源码解析

    多线程:(百度百科借一波定义) 多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术.具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提 ...

  7. java中Map,List与Set的区别(转)

    Set,List,Map的区别 java集合的主要分为三种类型: Set(集) List(列表) Map(映射) 要深入理解集合首先要了解下我们熟悉的数组: 数组是大小固定的,并且同一个数组只能存放类 ...

  8. 浅谈Java中的Set、List、Map的区别(转)

    对JAVA的集合的理解是想对于数组: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),JAVA集合可以存储和操作数目不固定的一组数据. 所有的JAVA集合都位于 java ...

  9. des (C语言)

    /** * \file des.h * * \brief DES block cipher * * Copyright (C) 2006-2010, Brainspark B.V. * * This ...

随机推荐

  1. centos 7 安装nvidia显卡驱动

    How to install Nvidia drivers in CentOS 7 - Tutorial :  http://www.dedoimedo.com/computers/centos-7- ...

  2. HTML5 唤起 APP

    <p><a href="xxx://app/question/95">点击跳转,直接回帖报名</a></p> /* global n ...

  3. proc文件系统探索 之 根目录下的文件[1]

    2.1根目录下的文件2.1.1lock文件内核锁,记录与被打开的文件有关的锁信息. 该文件显示当前被内核锁定的文件.该文件包含的内容是内核调试数据,根据使用的系统的这些数据会变化很大.一个/proc/ ...

  4. React Native(一) FlexBox布局

    欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/53241550 本文出自:[余志强的博客] 在React Native ...

  5. 【mybatis深度历险系列】mybatis中的输入映射和输出映射

    在前面的博文中,小编介绍了mybatis的框架原理以及入门程序,还有mybatis中开发到的两种方法,原始开发dao的方法和mapper代理方法,今天博文,我们来继续学习mybatis中的相关知识,随 ...

  6. ML学习分享系列(1)_计算广告小窥[上]

    原作:面包包包包包包 修改:寒小阳 && 龙心尘 时间:2016年1月 出处: http://blog.csdn.net/breada/article/details/50572914 ...

  7. Servlet规范总结

    Servlet接口 Servlet规范的核心接口即是Servlet接口,它是所有Servlet类必须实现的接口,在Java Servelt API中已经提供了两个抽象类方便开发者实现Servlet类, ...

  8. JAVA面向对象-----接口的概述

    接口的概述 **接口(interface):**usb接口,主要是使用来拓展笔记本的功能,那么在java中的接口主要是使用来拓展定义类的功能,可以弥补java中单继承的缺点. class Pencil ...

  9. 一个 Linux 上分析死锁的简单方法

    简介 死锁 (deallocks): 是指两个或两个以上的进程(线程)在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这 ...

  10. python学习资料整理

    [1] The Python Tutorial [2] Numpy Quick Start Tutorial [3] Python-OpenCV [4] http://www.learnpython. ...