也不知是怎么,以前没看懂为什么要用二分图,现在就懂了,以后也许碰到类似的题目还会想到用二分图,因为当i<j<k,且num[i] < num[j] && num[i] > num[k]的时候,肯定是不能将i和j放在同一个栈了(是放在同一个栈,不是同时在一个栈里面。)
嗯,上代码把:
#include <stdio.h>
#include <stdlib.h>
int num[1000];
int min[1000];
int map[1000000], next[1000000];
int end, head[1000];
void add(int a, int b)
{
map[end] = b;
next[end] = head[a];
head[a] = end++;
}
int group[1000];
void srch(int i, int k)
{
int j, t;
group[i] = k;
for(j = head[i]; j != -1; j = next[j]){
t = map[j];
if(group[t] == 0){
srch(t, 3 - k);
}else if(group[t] != 3 - k){
printf("0\n");
exit(0);
}
}
}
int stack[2][1000];
int top[2];
int output[2000];
int last;
void push(int k, int id)
{
stack[id][top[id]++] = k;
}
int gettop(int id)
{
if(top[id] == 0){
return 0xFFFFFFF;
}
return stack[id][top[id] - 1];
}
int pop(int id)
{
return stack[id][--top[id]];
}
int main(int argc, char **argv)
{
int i, j;
int n;
scanf("%d", &n);
for(i = 0; i < n; i++){
head[i] = -1;
scanf("%d", &num[i]);
}
min[n - 1] = num[n - 1];
for(i = n - 2; i >= 0; i--){
if(min[i + 1] > num[i]){
min[i] = num[i];
}else{
min[i] = min[i + 1];
}
}
for(i = 0; i < n - 2; i++){
for(j = i + 1; j < n - 1; j++){
if(num[i] < num[j] && num[i] > min[j + 1]){
add(i, j);
add(j, i);
}
}
}
for(i = 0; i < n; i++){
if(group[i] == 0){
srch(i, 1);
}
}
i = 1;
j = 0;
while(i <= n){
while(group[j] == 1 && num[j] < gettop(0)){
output[last++] = 'a';
push(num[j], 0);
j++;
}
while(gettop(0) == i){
output[last++] = 'b';
pop(0);
i++;
}
while(group[j] == 2 && num[j] < gettop(1)){
output[last++] = 'c';
push(num[j], 1);
j++;
}
while(gettop(1) == i){
output[last++] = 'd';
pop(1);
i++;
}
}
for(i = 0; i < last; i++){
if(i != 0){
printf(" ");
}
printf("%c", output[i]);
}
printf("\n");
return 0;
}