Water pipe
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 2508 | Accepted: 715 |
Description
The Eastowner city is perpetually haunted with water supply shortages, so in order to remedy this problem a new water-pipe has been built. Builders started the pipe from both ends simultaneously, and after some hard work both halves were connected. Well, almost. First half of pipe ended at a point (x1, y1), and the second half -- at (x2, y2). Unfortunately only few pipe segments of different length were left. Moreover, due to the peculiarities of local technology the pipes can only be put in either north-south or east-west direction, and be connected to form a straight line or 90 degree turn. You program must, given L1, L2, ... Lk -- lengths of pipe segments available and C1, C2, ... Ck -- number of segments of each length, construct a water pipe connecting given points, or declare that it is impossible. Program must output the minimum required number of segments.
Constraints
1 <= k <= 4, 1 <= xi, yi, Li <= 1000, 1 <= Ci <= 10
Constraints
1 <= k <= 4, 1 <= xi, yi, Li <= 1000, 1 <= Ci <= 10
Input
Input contains integers x1 y1 x2 y2 k followed by 2k integers L1 L2 ... Lk C1 C2 ... Ck
Output
Output must contain a single integer -- the number of required segments, or −1 if the connection is impossible.
Sample Input
20 10 60 50 2 70 30 2 2
Sample Output
4
题意:
给出K种长度的水管,并告诉每种长度有多少根,要求用这些水管从(x1,y1)一直铺到(x2,y2),最少使用多少根水管,水管可以交叉。
注意水管铺的范围坐标在0 ~ 1000
剪枝很重要,H值得设置如下:
假设现在只考虑一个坐标,那么BFS计算出可能到达的所有单个坐标的最少管道数量,
而对于当前的点x,y,它到达终点的管道数量,一定能保证大于等于Bfs单座标数+当前数,
Code:
Status | Accepted |
---|---|
Time | 641ms |
Memory | 744kB |
Length | 2111 |
Lang | G++ |
Submitted | 2017-10-06 16:45:14 |
Shared |
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int Max = 6;
bool flg;
int K, lim, sum;
int x1, y1, x2, y2;
int L[Max], C[Max], H1[1005], H2[1005];
int dd[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
void getint(int & num){
char c; int flg = 1; num = 0;
while((c = getchar()) < '0' || c > '9') if(c == '-') flg = -1;
while(c >= '0' && c <= '9'){ num = num * 10 + c - 48; c = getchar(); }
num *= flg;
}
int Bfs_H(int * H, int s){
queue<int>Q;
H[s] = 0;
Q.push(s);
while(! Q.empty()){
int tmp = Q.front(); Q.pop();
for(int i = 1; i <= K; ++ i){
int x = tmp - L[i];
if(x > 0 && H[x] == -1)
H[x] = H[tmp] + 1,
Q.push(x);
x += (L[i] << 1);
if(x <= 1000 && H[x] == -1)
H[x] = H[tmp] + 1,
Q.push(x);
}
}
}
void Dfs(int x, int y, int now, int *state){
if(now > lim) return ;
if(x == x2 && y == y2){flg = 1; return ;}
if(now + H1[x] > lim || now + H2[y] > lim) return ;
int newstate[Max];
memcpy(newstate, state, sizeof newstate);
for(int i = 1; i <= K; ++ i) if(newstate[i]){
-- newstate[i];
for(int j = 0; j < 4; ++ j){
int xx = x + L[i] * dd[j][0];
int yy = y + L[i] * dd[j][1];
if(xx >= 0 && yy >= 0 && xx <= 1000 && yy <= 1000)
Dfs(xx, yy, now + 1, newstate);
if(flg) return ;
}
++ newstate[i];
}
}
int main(){
getint(x1), getint(y1), getint(x2), getint(y2);
getint(K);
for(int i = 1; i <= K; ++ i) getint(L[i]);
for(int i = 1; i <= K; ++ i) getint(C[i]), sum += C[i];
if(x1 == x2 && y1 == y2){puts("0"); return 0;}
memset(H1, -1, sizeof H1 );
memset(H2, -1, sizeof H2 );
Bfs_H(H1, x2);
Bfs_H(H2, y2);
for(lim = 1; lim <= sum; ++ lim){
Dfs(x1, y1, 0, C);
if(flg) break;
}
if(flg) printf("%d\n", lim);
else puts("-1");
return 0;
}