1
0
Fork 0

Add others/other/vdd.cpp

This commit is contained in:
Nguyễn Gia Phong 2017-08-31 15:21:04 +07:00
parent 95b46c031c
commit bc836411b0
2 changed files with 202 additions and 0 deletions

View File

@ -938,3 +938,44 @@ Một dòng duy nhất chứa số đơn vị khối nước đọng lại.
| NUOC.INP | NUOC.OUT |
| -------------------------------------------------------------------- | :------: |
| 5 5<br>9 9 9 9 9<br>9 2 2 2 9<br>9 2 5 2 9<br>9 2 2 2 9<br>9 9 9 9 9 | 60 |
## Vượt đại dương
Bản đồ của một vùng biển được cho bởi một lưới các ô vuông đơn vị gồm N dòng, N
cột (N ≤ 100), trong đó vùng biển được đánh số 0 và các vùng khác được đánh số
1\. Giả sử rằng bên ngoài biên của lưới là đại dương mênh mông. Một hòn đảo là
một tập các ô vuông có giá trị 1 và có chung cạnh với nhau, số các ô vuông này
chính là diện tích của hòn đảo.
Một ngư dân sống trên một hòn đảo sẽ vượt biển tìm đến một hòn đảo mới rộng lớn
hơn để sinh sống. Từ một ô vuông trên bản đồ, anh ta chỉ được đến một ô khác
chung cạnh với ô vuông mà anh ta đang đứng (cả trên cạn lẫn dưới biển). Khi
vượt đại dương anh ta không muốn dừng chân trên một hòn đảo nào khác ngoài hòn
đảo mà anh ta muốn đến.
### Yêu cầu
Cho trước bản đồ của vùng biển và vị trí của anh ngư dân, hãy cho biết có một
hòn đảo nào khác có diện tích lớn hơn diện tích hòn đảo mà anh ngư dân đang
sinh sống. Nếu có hãy chỉ giúp anh ngư dân một hành trình vượt biển đến một hòn
đảo lớn hơn sao cho đoạn đường vượt biển là ngắn nhất. Nếu với cùng độ dài đoạn
đường đó mà có thể đến được các đảo khác nhau thì ưu tiên đến đảo có diện tích
lớn nhất.
### Dữ liệu
* Dòng đầu ghi số N cho biết kích thước bản đồ, hai số x, y là vị trí dòng và
cột trên bản đồ nơi mà anh ngư dân đang sinh sống.
* N dòng tiếp theo, mỗi dòng ghi N số cho biết nội dung bản đồ các số trên cùng
một dòng cách nhau ít nhất một khoảng trắng.
### Kết quả
* Nếu không tìm được một hòn đảo thích hợp thì ghi số 0.
* Nếu tìm được thì ghi độ dài của hành trình.
### Ví dụ
| VDD.INP | VDD.OUT |
| ---------------------------------------------------------------------- | :-----: |
| 5 1 5<br>0 0 0 1 1<br>0 0 0 0 1<br>1 1 0 0 1<br>1 1 0 0 0<br>0 1 0 0 0 | 2 |

161
others/other/vdd.cpp Normal file
View File

@ -0,0 +1,161 @@
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>
#include <functional>
using namespace std;
#define POINT(x, y) (((x) << 7) + (y))
#define ENC(s, x, y) (((s) << 14) + ((x) << 7) + (y))
void
explore(short x, short y, short n, short a[102][102], short* p[102][102])
{
short i, j;
short* area = p[x][y];
queue<short> q;
q.push(POINT(x, y));
while (!q.empty())
{
i = q.front();
q.pop();
j = i & 127;
i >>= 7;
if (i > 1 && a[i - 1][j] && !p[i - 1][j])
{
(*area)++;
p[i - 1][j] = area;
q.push(POINT(i - 1, j));
}
if (i < n && a[i + 1][j] && !p[i + 1][j])
{
(*area)++;
p[i + 1][j] = area;
q.push(POINT(i + 1, j));
}
if (j > 1 && a[i][j - 1] && !p[i][j - 1])
{
(*area)++;
p[i][j - 1] = area;
q.push(POINT(i, j - 1));
}
if (j < n && a[i][j + 1] && !p[i][j + 1])
{
(*area)++;
p[i][j + 1] = area;
q.push(POINT(i, j + 1));
}
}
}
int
main()
{
short n, x, y, i, j, a[102][102] = {};
ifstream infile;
infile.open("VDD.INP");
infile >> n >> x >> y;
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
infile >> a[i][j];
infile.close();
short* p[102][102] = {};
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
if (a[i][j] && !p[i][j])
{
p[i][j] = (short*) malloc(sizeof(short));
*p[i][j] = 1;
explore(i, j, n, a, p);
}
priority_queue<long, vector<long>, greater<long>> heap;
bool visited[102][102] = {};
queue<short> q;
visited[x][y] = true;
q.push(POINT(x, y));
while (!q.empty())
{
i = q.front();
q.pop();
j = i & 127;
i >>= 7;
if (!(a[i + 1][j] && a[i][j + 1] && a[i - 1][j] && a[i][j - 1]))
heap.push(POINT(i, j));
if (i > 1 && !visited[i - 1][j] && a[i - 1][j])
{
q.push(POINT(i - 1, j));
visited[i - 1][j] = true;
}
if (i < n && !visited[i + 1][j] && a[i + 1][j])
{
q.push(POINT(i + 1, j));
visited[i + 1][j] = true;
}
if (j > 1 && !visited[i][j - 1] && a[i][j - 1])
{
q.push(POINT(i, j - 1));
visited[i][j - 1] = true;
}
if (j < n && !visited[i][j + 1] && a[i][j + 1])
{
q.push(POINT(i, j + 1));
visited[i][j + 1] = true;
}
}
short* current = p[x][y], s = 12345;
long tmp;
while (!heap.empty())
{
tmp = heap.top();
heap.pop();
i = tmp >> 7 & 127;
j = tmp & 127;
tmp >>= 14;
if (tmp > s)
break;
if (p[i][j] && p[i][j] != current)
if (*p[i][j] <= *current)
continue;
else
{
s = tmp;
*current = *p[i][j];
}
tmp++;
if (i && !visited[i - 1][j])
{
heap.push(ENC(tmp, i - 1, j));
visited[i - 1][j] = true;
}
if (i < n + 1 && !visited[i + 1][j])
{
heap.push(ENC(tmp, i + 1, j));
visited[i + 1][j] = true;
}
if (j && !visited[i][j - 1])
{
heap.push(ENC(tmp, i, j - 1));
visited[i][j - 1] = true;
}
if (j < n + 1 && !visited[i][j + 1])
{
heap.push(ENC(tmp, i, j + 1));
visited[i][j + 1] = true;
}
}
ofstream outfile;
outfile.open("VDD.OUT");
outfile << (s == 12345 ? 0 : s - 1) << endl;
outfile.close();
return 0;
}