一个港口上有N辆车排队,有卡车和货车,用0代表卡车,1代表货车,现在有如下规则,当同类型的车排队时,先来的车在前面,而卡车和货车来时,卡车先,除了以上规则外,还有如下规则:当有4辆卡车时,必须有一辆货车,当没有货车时,卡车可以排上,当卡车不到4量时,可以用货车补上,下面是一个例子
7
输入:0 0 1 0 1 0 0
输出:0 1 3 5 2 6 4
下面讲下思路:
对于输入我们可以编号,从0开始:
输入:0 0 1 0 1 0 0
编号:0 1 2 3 4 5 6
此时,可以先对同样的0和1进行排序,要稳定排序,此时可以使用基数排序
排序:0 0 0 0 0 1 1
编号:0 1 3 5 6 2 4
接着按照规则每4个0有个1开始排序
0 0 0 0 0 0 0 1 1 1 1 1 1 1
| |
index0 index1
index0和index1分别往后移动,移动规则如下:
每碰到4个0,排一个1
原数组:0 0 0 0 0 0 0 1 1 1 1 1 1 1
输出: 0 0 0 0 1 0 0 0 1 1 1 1 1 1
如果还有不明白的可以配合代码看下:
#include <iostream> #include <vector> #include <map> using namespace std; int main() { int N; /**/ cin >> N; // 输入总车数 vector<int> vec; vector<int> seq; seq.resize(N); vec.resize(N); int ke,huo; ke = huo = 0; for ( int i=0; i<N; ++i ) { int num; cin >> num; vec[i] = num; if ( num == 0 ) ke++; else huo++; } int index1 = N; int index0 = ke; for ( int i=N-1; i>=0; --i ) // 基数排序,稳定排序 { if ( vec[i] == 1 ) seq[--index1] = i; else seq[--index0] = i; } // 如今 seq中保存了下标 vector<int> ret; ret.resize(N); int k,i,j; k = 0; // i表示卡车开始坐标,j表示货车开始 for ( i=0,j=ke; i<ke && j<N; ) { ret[k++] = seq[i++]; if ( k % 4 == 0 ) // 每4个0,一个1 ret[k++] = seq[j++]; } while ( i < ke ) ret[k++] = seq[i++]; while ( j < N ) ret[k++] = seq[j++]; for ( int i=0; i<N; ++i ) cout<<ret[i]<<" "; cout<<endl; }