zoukankan      html  css  js  c++  java
  • [LuoguP3668][USACO17OPEN]现代艺术2

    [LuoguP3668][USACO17OPEN]Modern Art2(Link

    现在你有一块长为(N)的画布,每次可以选择一段连续的区间进行颜色填涂,新颜色会覆盖旧颜色。每一次填涂都要耗费一天时间。在所有的填涂中每一种颜色只能用1次。求将画布变为目标序列的最小天数。如果不能完成填涂那么输出(-1)

    首先我们要知道填涂的方式以及什么叫做填涂不合法。

    Pic1

    上面的这个方案明显是合法的,我们先涂上“底色”(Green)然后再涂(Red)就好。

    Pic2

    上面的这个情况,你发现无论怎么涂都是不合法。那么我们找到了一个显然的规律:有交叉的颜色就不合法。

    于是问题变得简单了,我们用一个栈直接记录一下花费时间就可以了。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std ;
    typedef long long LL ;
    const int MAXN = 100010 ;
    const int MAXM = 100010 ;
    int N, Line[MAXN], S[MAXN], S1[MAXN], Top, S2[MAXN], Sum ;
    
    inline int Read() {
    	int X = 0, F = 1 ; char ch = getchar() ;
    	while (ch > '9' || ch < '0') F = (ch == '-' ? - 1 : 1), ch = getchar() ;
    	while (ch >= '0' && ch <= '9') X=(X<<1)+(X<<3)+(ch^48), ch = getchar() ;
    	return X * F ;
    }
    
    int main() {
    	N = Read() ;
    	for (int i = 1 ; i <= N ; i ++)  {
    		Line[i] = Read() ; S2[Line[i]] = i ;
    		if (! S1[Line[i]]) S1[Line[i]] = i ;
    	}	S2[Line[N + 1]] = N + 1 ;
    	for (int i = 0 ; i <= N + 1 ; i ++) {
    		if (i == S1[Line[i]]) S[++ Top] = Line[i], Sum = max(Top, Sum) ;
    		if (Line[i] != S[Top]) {
    			printf("-1") ; return 0 ;
    		}	if (i == S2[Line[i]]) Top -- ;
    	}
    	printf("%d", Sum) ;
    }
    
  • 相关阅读:
    linux signal之初学篇
    Eclipse 每次打开workspace目录记录位置?
    [Clojure] A Room-Escape game, playing with telnet and pure-text commands
    孔雀翎----《Programming C# 》中国版 文章4版
    js一些编写的函数
    KVM,QEMU核心分析
    apche commons项目简介
    java基础—网络编程———建立聊天的形式
    学习算法
    css+html+js实现多级下拉和弹出菜单
  • 原文地址:https://www.cnblogs.com/sue_shallow/p/P3668.html
Copyright © 2011-2022 走看看