Loading

题解—简单的填数

其实,改这到题之前,一切都很顺利。

很麻烦,所以这个应该慢慢想。

所以,改的东西出毛病了,不能着急,需要静下心来想一想。
该了一下午加一晚上就很亏。

这个东西,就是设计一个跳得快的数组,一个慢的。
分别记录他们的值和有几个连续的。
如果\(a[i]\)没有值,那么很简单,按照题意转移就行了。

如果有值

  • 如果这个值很快的或者慢的的上一个值相等,直接继承过来加一。
  • 如果不相等,进行分类讨论。
    • 如果是慢的,因为要尽量让他慢,所以直接设成1
    • 如果是快的,因为想要让他快点,所以我们想把它设置成2,这样他就能更快的扩展,但是如果出现一下情况,我们就只能让他是\(1\)

想一想为什么我们可以直接设置成\(2\), 是因为之前快的跑的太快了,所以导致他到达一个有\(a[i]\)的数字的时候,他自身的值大于\(a[i]\)
导致他有一些值是浪费的。

所以直接设置成\(2\),可以利用他的一些浪费的,让他跑的更快。
但是,出现以下情况,只能是\(1\)

  • 上一个\(a[i]\)有数,并且是这个\(a[i]-1\)
  • 上一个\(a[i]\)没数,上一个\(up[i]\)正好是这个\(a[i]-1\)

第一个很好理解,上一个被强迫是\(a[i]-1\)了,他这只能是新开的一个
第二个也还行,因为上一个\(a[i]\)没数,他都只能到\(a[i]-1\),说明之前没浪费也只能到这,所以也是新开的一个。

然后就行了。

输出方案,题解做法就是因为快的肯定对于他和她之前的的数是合法的,所以利用这个性质倒退
因为我是自己说服我自己的,所以具体为什么我也懒得写了。

\(dfs\)可以过,所以这里还是贴一个\(dfs\)的码吧。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <assert.h>
#define R register int
#define int long 
#define scanf Ruusupuu = scanf
#define printf Ruusupuu = printf

int Ruusupuu ;

using namespace std ;
typedef long long L ;
typedef long double D ;
typedef pair< int , int > PI ;
const int N = 2e5 + 10 ;

inline int read(){
	int w = 0 ; bool fg = 0 ; char ch = getchar() ;
	while( ch < '0' || ch > '9' ) fg |= ( ch == '-' ) , ch = getchar() ;
	while( ch >= '0' && ch <= '9' ) w = ( w << 1 ) + ( w << 3 ) + ( ch - '0' ) , ch = getchar() ;
	return fg ? -w : w ; 
}

int n , a [N] , lo [N] , sh [N] , lpos [N] , spos [N] , cnt , vz [N] , cx [N] , ans [N] ;

inline void die(){ puts( "-1" ) , exit( 0 ) ; }

void sc(){
	n = read() ; for( R i = 1 ; i <= n ; i ++ ){
		a [i] = read() ;
		if( a [i] ) vz [++ cnt] = i ; 
	}
	if( a [1] && a [1] != 1 ) die() ;
	for( R i = 1 ; i <= n ; i ++ ){
		if( a [i] && a [i - 1] && a [i] < a [i - 1] ) die() ;
		if( a [i] && a [i - 1] && a [i + 1] && a [i] != a [i - 1] && a [i] != a [i + 1] ) die() ;
	}	 //先保证原序列合法(并没卵用)
}	

inline void pf(){
	for( R i = 1 ; i <= n ; i ++ ) printf( "%ld " , ans [i] ) ;
	exit( 0 ) ;	
} 

void dfs( int x  ){
	if( x == n + 1 ){
		if( ans [n] == a [n] && cx [ans [n]] >= 2 ) pf() ;
		else return ;
	} //printf( "%ld %ld %ld %ld %ld %ld %ld %ld\n" , x , ans [1] , ans [2] , ans [3] , ans [4] , ans [5] , ans [6] , ans [7] ) ; 
	int t = ans [x - 1] ;
	if( a [x] ){
		if( ( t == a [x] - 1 && cx [t] == 1 ) || ( t + 1 < a [x] ) ) return ;
		ans [x] = a [x] , cx [a [x]] ++ , dfs( x + 1 ) , cx [a [x]] -- ;
	}
	else if( cx [t] == 1 ) ans [x] = ans [x - 1] , cx [ans [x]] ++ , dfs( x + 1 ) , cx [ans [x]] -- ;  
	else if( cx [t] == 5 ) ans [x] = ans [x - 1] + 1 , cx [ans [x]] ++ , dfs( x + 1 ) , cx [ans [x]] -- ;
	else{
		ans [x] = ans [x - 1] , cx [ans [x]] ++ , dfs( x + 1 ) , cx [ans [x]] -- ;
		ans [x] = ans [x - 1] + 1 , cx [ans [x]] ++ , dfs( x + 1 ) , cx [ans [x]] -- ;
	}
}

void work(){
	lo [1] = lpos [1] = sh [1] = spos [1] = 1 ;
	for( R i = 2 ; i <= n ; i ++ ){
	//	printf( "%ld %ld %ld %ld %ld\n" , lo [i - 1] , lpos [i - 1] , sh [i - 1] , spos [i - 1] , a [i] ) ;
		if( a [i] ){
			
			if( lo [i - 1] < a [i] && lpos [i - 1] < 2 ) die() ;			
			if( sh [i - 1] > a [i] ) die() ;
			if( sh [i - 1] == a [i] && spos [i - 1] == 5 ) die() ;
			
			lo [i] = sh [i] = a [i] ;
		//	printf( "%ld %ld %ld\n" , lo [i - 1] , sh [i - 1] , a [i] ) ;
			
			spos [i] = ( ( sh [i - 1] == a [i] ) ? ( spos [i - 1] + 1 ) : ( 1 ) ) ; 
		//	lpos [i] = max( spos [i] , ( ( lo [i - 1] == a [i] ) ? ( lpos [i - 1] + 1 ) : ( 1 ) ) ) ;   
			lpos [i] = ( ( lo [i - 1] == a [i] ) ? ( lpos [i - 1] + 1 ) : ( ( ( a [i - 1] + 1 == a [i] ) && ( a [i - 1] ) ) || ( !a [i - 1] && ( lo [i - 1] == a [i] - 1 ) ) ) ? 1 : 2 ) ;
		//	printf( "%ld %ld\n" , lpos [i] , spos [i] ) ;
		}
		else{
			if( lpos [i - 1] >= 2 ) lpos [i] = 1 , lo [i] = lo [i - 1] + 1 ;
			else lpos [i] = lpos [i - 1] + 1 , lo [i] = lo [i - 1] ;
			if( spos [i - 1] == 5 ) spos [i] = 1 , sh [i] = sh [i - 1] + 1 ;
			else spos [i] = spos [i - 1] + 1 , sh [i] = sh [i - 1] ;
		} 
//		printf("%ld %ld %ld %ld\n",lo[i],lpos[i],sh[i],spos[i]);
	} a [n] =  lpos [n] >= 2 ? lo [n] : lo [n] - 1 ;
	printf( "%ld\n" , a [n] ) ;
	
	ans [1] = 1 , cx [1] ++ , dfs( 2 ) ;
	for( R i = 1 ; i <= n ; i ++ ) printf( "%ld " , ans [i] ) ;
}

signed main(){
	sc() ;
	work() ;
	return 0 ; 
}
posted @ 2021-07-13 06:33  Soresen  阅读(44)  评论(0)    收藏  举报