Sicily 2661. Walking

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;
}                                 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值