1. tractor
题目描述
农场上有N(1 <= N <= 50,000)堆草,放在不同的地点上。FJ有一辆拖拉机,也在农场上。拖拉机和草堆都表示为二维平面上的整数坐标,坐标值在1..1000的范围内。拖拉机的初始位置与所有草堆不同。
FJ开拖拉机时,只能平行于坐标轴(即东、南、西、北四个方向),而且每次开动的一段必须是整数长度。
例如,他可以向北开2个单位长度,然后向东开3个单位长度。拖拉机不能开到草堆的位置。
请帮助FJ计算出最少要移动多少个草堆,他才能将拖拉机开回坐标原点。
拖拉机可以开到1..1000之外的地方去。
输入
第1行: 3个整数,即N 和拖拉机的初始位置 (x,y)
第2..1+N行: 每行2个整数,表示一堆草的位置 (x,y)
输出
第1行: FJ必须移动的最少的草堆的数量
样例输入
7 6 3
6 2
5 2
4 3
2 1
7 3
5 4
6 4
样例输出
DP代码(以下为lemonoil的代码):
题目描述
农场上有N(1 <= N <= 50,000)堆草,放在不同的地点上。FJ有一辆拖拉机,也在农场上。拖拉机和草堆都表示为二维平面上的整数坐标,坐标值在1..1000的范围内。拖拉机的初始位置与所有草堆不同。
FJ开拖拉机时,只能平行于坐标轴(即东、南、西、北四个方向),而且每次开动的一段必须是整数长度。
例如,他可以向北开2个单位长度,然后向东开3个单位长度。拖拉机不能开到草堆的位置。
请帮助FJ计算出最少要移动多少个草堆,他才能将拖拉机开回坐标原点。
拖拉机可以开到1..1000之外的地方去。
输入
第1行: 3个整数,即N 和拖拉机的初始位置 (x,y)
第2..1+N行: 每行2个整数,表示一堆草的位置 (x,y)
输出
第1行: FJ必须移动的最少的草堆的数量
样例输入
7 6 3
6 2
5 2
4 3
2 1
7 3
5 4
6 4
样例输出
1
本题提供两种做法
1.最短路
当走到边界时就可以乱跑了啦啦啦。
所以我们就往边界跑。
2.我的某Lee姓Friend给出了一个比较迷的解法,根据方向与顺序跑8次DP。
最短路代码:
#include <cstdio>
#include <queue>
using namespace std;
struct Point
{
int x,y;
Point(int _x, int _y)
{
x = _x;
y = _y;
}
Point(void)
{
x=y=0;
}
};
queue<Point>zero_away,one_away;
int A[1002][1002],D[1002][1002];
int relax(int curx, int cury, int x, int y)
{
if (x>=0 && x<=1001 && y>=0 && y<=1001 && (D[x][y]==0 || D[curx][cury]+A[x][y]<D[x][y]))
{
D[x][y] = D[curx][cury]+A[x][y];
if (A[x][y]==0)
zero_away.push(Point(x,y));
else one_away.push(Point(x,y));
}
}
int main()
{
Point p;
int i, n;
freopen("tractor.in", "r", stdin);
freopen("tractor.out", "w", stdout);
scanf("%d%d%d",&n,&p.x,&p.y);
D[p.x][p.y] = 1;
zero_away.push(p);
for(i = 0; i < n; i++)
{
scanf ("%d%d",&p.x,&p.y);
A[p.x][p.y] = 1;
}
while(!zero_away.empty() || !one_away.empty()) {
if(zero_away.empty())
while(!one_away.empty())
{
zero_away.push(one_away.front());
one_away.pop();
}
p = zero_away.front();
zero_away.pop();
relax(p.x,p.y,p.x-1,p.y);
relax(p.x,p.y,p.x+1,p.y);
relax(p.x,p.y,p.x,p.y-1);
relax(p.x,p.y,p.x,p.y+1);
}
printf ("%d\n", D[0][0]-1);
return 0;
}
DP代码(以下为lemonoil的代码):
原文章http://blog.csdn.net/lemonoil/article/details/53130792?locationNum=2&fps=1
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<queue>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<stack>
#define rez(i,x,y) for(int i=x;i>=y;i--)
#define res(i,x,y) for(int i=x;i<=y;i++)
#define INF 2100000000
#define ll long long
#define clr(x) memset(x,0,sizeof(x))
#define N 100005
#define NAME "tractor"
#define minn(x,y,z) x=min(x,min(y,z))
using namespace std;
inline void readin(int &res) {
static char ch;
while ((ch = getchar()) < '0' || ch > '9');
res = ch - 48;
while ((ch = getchar()) >= '0' && ch <= '9')
res = res * 10 + ch - 48;
}
struct node{
int x,y;
};
int a[1005][1005];
int dp[1005][1005];
queue<node> q;
int n,r,c,op;
int ans=INF;
void dfs(){
while(!q.empty()){
node k=q.front();q.pop();
node t;
if(k.x==0&&k.y==0){
ans=0;return;
}
if(k.x>1000||k.y>1000||k.x<0||k.y<0){
ans=0;return;
}
if(!a[k.x+1][k.y]&&!dp[k.x+1][k.y]){
dp[k.x+1][k.y]=1;t.x=k.x+1;t.y=k.y;
q.push(t);
}
if(!a[k.x][k.y+1]&&!dp[k.x][k.y+1]){
dp[k.x][k.y+1]=1;t.x=k.x;t.y=k.y+1;
q.push(t);
}
if(!a[k.x][k.y-1]&&!dp[k.x][k.y-1]){
dp[k.x][k.y-1]=1;t.x=k.x;t.y=k.y-1;
q.push(t);
}
if(!a[k.x-1][k.y]&&!dp[k.x-1][k.y]){
dp[k.x-1][k.y]=1;t.x=k.x-1;t.y=k.y;
q.push(t);
}
}
}
int main(){
freopen(NAME".in","r",stdin);
//freopen(NAME".out","w",stdout);
readin(n);readin(r);readin(c);
for(int x,y,i=1;i<=n;i++){
readin(x);readin(y);a[x][y]=1;
}
node k;
k.x=r,k.y=c;
clr(dp);
//dfs();
clr(dp);
for(int i=0;i<=1001;i++){
for(int j=0;j<=1001;j++){
dp[i][j]=min(dp[i-1][j],dp[i][j-1]);
dp[i][j]+=a[i][j];
}
}
ans=min(ans,dp[r][c]);
clr(dp);
for(int i=1001;i>=0;i--){
for(int j=0;j<=1001;j++){
dp[i][j]=min(dp[i+1][j],dp[i][j-1]);
dp[i][j]+=a[i][j];
}
}
ans=min(ans,dp[r][c]);
clr(dp);
for(int i=0;i<=1001;i++){
for(int j=1001;j>=0;j--){
dp[i][j]=min(dp[i-1][j],dp[i][j+1]);
dp[i][j]+=a[i][j];
}
}
ans=min(ans,dp[r][c]);
clr(dp);
for(int i=1001;i>=0;i--){
for(int j=1001;j>=0;j--){
dp[i][j]=min(dp[i+1][j],dp[i][j+1]);
dp[i][j]+=a[i][j];
}
}
ans=min(ans,dp[r][c]);
clr(dp);
for(int i=0;i<=1001;i++){
for(int j=1001;j>=0;j--){
dp[j][i]=min(dp[j+1][i],dp[j][i-1]);
dp[j][i]+=a[j][i];
}
}
ans=min(ans,dp[r][c]);
clr(dp);
for(int i=0;i<=1001;i++){
for(int j=0;j<=1001;j++){
dp[j][i]=min(dp[j-1][i],dp[j][i-1]);
dp[j][i]+=a[j][i];
}
}
ans=min(ans,dp[r][c]);
clr(dp);
for(int i=1001;i>=0;i--){
for(int j=1001;j>=0;j--){
dp[j][i]=min(dp[j+1][i],dp[j][i+1]);
dp[j][i]+=a[j][i];
}
}
ans=min(ans,dp[r][c]);
clr(dp);
for(int i=1001;i>=0;i--){
for(int j=0;j<=1001;j++){
dp[j][i]=min(dp[j-1][i],dp[j][i+1]);
dp[j][i]+=a[j][i];
}
}
cout<<dp[r][c];
return 0;
}