题目:http://poj.org/problem?id=1068
AC代码(C++):
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <queue>
#include <math.h>
#include <string.h>
using namespace std;
int main(){
int m;
cin>>m;
for(int i = 0; i < m; i++){
int n;
int* p;
int* w;
cin>>n;
p = new int[n];
w = new int[n];
for(int i = 0; i < n; i++){
cin>>p[i];
p[i]--;
}
w[0] = 1;
for(int i = 1; i < n; i++){
for(int j = i-1; j >= 0; j--){
if(p[j+1]-p[j]>=1){
w[i] = i-j;
for(int k = j+1; k < n; k++)p[k]--;
break;
}
else if(j==0){//匹配括号在开头
w[i] = i-j+1;
for(int k = 0; k < n; k++)p[k]--;
break;
}
}
}
for(int i = 0; i < n; i++){
cout<<w[i];
if(i!=n-1)cout<<' ';
}
cout<<endl;
}
}
总结: 模拟题, 不需要暴力(或者暴力可能会超时?). 这题的思路是, 在计算w[i]的时候, 从p[j]往前找(j=i-1), 直到找到p[j+1]-p[j]大于等于1, 或者找到头, 则i位置匹配的括号就是在j+1和j中间那些左括号中取一个(或者在开头的左括号中), 取完后所有j+1往后包括j+1的p数组值减一(因为取走了一个左括号), 循环直到找到所有w[i]结束.