Codeforces--Balanced Tunnel
问题重述
Codeforces --- Balanced Tunnel
见链接http://codeforces.com/contest/1237/problem/B。
Solve
这道题的本质是找递增序列中出现的非递增数的数目。如果未发生超车情况,则进入的车在出去的时候,应该是一个递增的序列。
于是可以用一个pos[x]数组来记录标号为i的车出去时候的顺序,这样,当我们按照进入时候的顺序进行遍历时,如果车发生过超车现象,那么肯定有某辆入序靠后的车其先出去了,也就是pos[x]的值小于之前的最大值。以样例1为例。
进入顺序: 1 2 3 4 5
进入时车的标号顺序: 3 5 2 1 4
出去的顺序数组: 2 4 3 5 1
出去时车的标号顺序: 4 3 2 5 1
显然,按照35214的顺序遍历的时候,只需要每次保存遍历到当前位置时的最大出去的序号值,就可以判断出是否有超车了,代码如下,时间复杂度为O(n)。当然,这道题还可以采取求逆序对的方式来求解,复杂度为O(nlogn)。
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 static const int MAX = 1000000; 6 7 int arr[MAX]; 8 int pos[MAX]; 9 10 int main(){ 11 int n; 12 scanf("%d", &n); 13 14 // read arr 15 for(int i=1;i<=n;i++){ 16 scanf("%d", &arr[i]); 17 } 18 // construct pos 19 int num; 20 for(int i=1;i<=n;i++){ 21 scanf("%d", &num); 22 pos[num] = i; 23 } 24 25 // solve 26 int sum = 0; 27 int tmp = 0; 28 for(int i=1;i<=n;i++){ 29 tmp = max(tmp, pos[arr[i]]); 30 if(pos[arr[i]]<tmp){ 31 sum++; 32 } 33 } 34 printf("%d\n", sum); 35 return 0; 36 }