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. C++ 程序在运行时不显示dos界面

    在程序最开始处加一句: #pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" ) PS: 在VS中 ...

  2. 毕业回馈-89c51之定时器/计数器(Timer/Count)

    今天分享的是89c51系列单片机的内部资源定时器/计数器,在所有的嵌入式系统中都包含这两个内部功能. 首先先了解几个定时器/计数器相关的概念: •时钟周期:时钟周期 T 是时序中最小的时间单位,具体计 ...

  3. git清空某个文件的历史版本

    比如你要清空文件private.ini git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch priva ...

  4. 关于Java,那些我心存疑惑的事(不断更新中...)

    本文主要列出一些Java常用到确又让大家不怎么注意的问题. 将会不断更新,欢迎关注-- 如有觉得不合理之处,欢迎评论交流,没有火花怎么印象深刻? (1)Java到底是值传递?还是引用传递? 揪出这个问 ...

  5. Ubuntu安装telent服务器时出现:apt-get:Package has no installation

    当我在终端敲下这条命令的时候,系统就提示telnetd:apt-get:Package has no installation sudo apt-get install xinetd telnetd ...

  6. 硬件模块化机器人操作系统 Hardware Robot Operating System (H-ROS)

    原文网址:http://www.ros.org/news/2016/10/hardware-robot-operating-system-h-ros.html 推荐网址:https://h-ros.c ...

  7. 23 服务音乐的启动Demo4

    注意如果音乐服务和Activity在一个应用中那么将不会因为绑定的Activity销毁而关闭音乐 MainActivity.java package com.qf.day23_service_demo ...

  8. Linux动态频率调节系统CPUFreq之二:核心(core)架构与API

    上一节中,我们大致地讲解了一下CPUFreq在用户空间的sysfs接口和它的几个重要的数据结构,同时也提到,CPUFreq子系统把一些公共的代码逻辑组织在一起,构成了CPUFreq的核心部分,这些公共 ...

  9. 微软Telnet的回显功能开启

    win7和XP系统默认telnet的回显功能是关闭的.启用telnet回显功能:(1)首先进入命令行界面:输入telnet(2)进入Microsoft Telnet>命令提示符下,输入:set ...

  10. Swift函数柯里化(Currying)简谈

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 下面简单说说Swift语言中的函数柯里化.简单的说就是把接收多 ...