NOIP 2008 双栈排序 解体报告
也不知是怎么,以前没看懂为什么要用二分图,现在就懂了,以后也许碰到类似的题目还会想到用二分图,因为当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; }