2661. Walking
Constraints
Time Limit: 1 secs, Memory Limit: 256 MB
Description
In a city there’re ten thousand vertical streets represented by ten thousand line segments Li (i=0,1,…,9999) , end points of Li is (i,0) and (i,9999) . Besides these vertical streets , there’re some horizontal streets linking the vertical streets. Length of each horizontal street is 1, and no two horizontal streets link to the same point.
Now someone wants to walk across the city from (xs,9999) down to (xe,0) . He will walk down a vertical street until he reaches a horizontal street, then he turn left or right to walk across the horizontal street, and then he will walk down the vertical street where he is. So once the streets and xs are given, the road he walks is determined, and he may not be able to walk to (xe,0) . The problem is to build as least extra horizontal streets as possible to let him walk to (xe,0) . The streets to be built should satisfy: each horizontal street links two vertical streets with length 1, and for all the streets(old and newly built streets) , no two of them link to the same point.
Input
All input data are integers separated with blanks, and there’re at most 100 test cases.
The first line of each test case is xs , xe (0<=xs,xe<=9999) and m (0<=m<=100).m is the number of old horizontal streets.
Then m lines follow, each contains two number xi , yi (1<=xi,yi<=9998) indicating one horizontal street linking point (xi,yi) and point(xi+1,yi).
xs=xe=m=0 indicates the end of input data and should not be processed.
Output
For each test case output the least number of horizontal streets needed to be built in a single line.
Sample Input
1 1 2 1 1000 2 999 0 0 0
Sample Output
1
Problem Source
系列热身赛4@2011年上半学期算法考试和4+2选拔赛
// Problem#: 2661
// Submission#: 3593150
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
using namespace std;
const int MAXM = 202;
const int MAXC = 9999;
int dp[MAXM][MAXM];
bool cmp(const int & a, const int & b) {
return a > b;
}
int main() {
int xs, xe, m, xn, yn;
int sx[MAXM], sy[MAXM];
int mx[MAXC + 1], my[MAXC + 1];
int i, j, k;
vector<int> xValue, yValue, streetList[MAXM];
while (scanf("%d%d%d", &xs, &xe, &m), xs || xe || m) {
xValue.clear();
yValue.clear();
xValue.push_back(xs);
xValue.push_back(xe);
yValue.push_back(0);
yValue.push_back(MAXC);
for (i = 0; i < m; i++) {
scanf("%d%d", sx + i, sy + i);
xValue.push_back(sx[i]);
xValue.push_back(sx[i] + 1);
yValue.push_back(sy[i]);
}
sort(xValue.begin(), xValue.end());
xn = unique(xValue.begin(), xValue.end()) - xValue.begin();
for (i = 0; i < xn; i++) mx[xValue[i]] = i;
sort(yValue.begin(), yValue.end(), cmp);
yn = unique(yValue.begin(), yValue.end()) - yValue.begin();
for (i = 0; i < yn; i++) my[yValue[i]] = i;
for (i = 0; i < yn; i++) streetList[i].clear();
for (i = 0; i < m; i++)
streetList[my[sy[i]]].push_back(sx[i]);
for (i = 0; i < yn; i++)
for (j = 0; j < xn; j++) dp[i][j] = MAXC;
for (i = 0; i < xn; i++) dp[0][i] = abs(xValue[i] - xs);
for (i = 1; i < yn; i++) {
for (j = 0; j < xn; j++) {
for (k = 0; k < xn; k++) {
if (dp[i - 1][j] + abs(xValue[j] - xValue[k]) < dp[i][k]) {
dp[i][k] = dp[i - 1][j] + abs(xValue[j] - xValue[k]);
}
}
}
for (j = 0; j < streetList[i].size(); j++) {
int t1 = mx[streetList[i][j]], t2 = mx[streetList[i][j] + 1];
swap(dp[i][t1], dp[i][t2]);
}
}
printf("%d\n", dp[yn - 1][mx[xe]]);
}
return 0;
}