社区讨论
引水入城 WA 50分
P1514[NOIP 2010 提高组] 引水入城参与者 4已保存回复 9
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 9 条
- 当前快照
- 1 份
- 快照标识符
- @mi7dxqes
- 此快照首次捕获于
- 2025/11/20 20:06 4 个月前
- 此快照最后确认于
- 2025/11/20 20:06 4 个月前
具体思路如下:
- 首先可证 每个水泵能覆盖的沙漠为连续区间
- 记忆化DFS 出每个水泵能覆盖的区间
- 判断 每一个沙漠在DFS过程中是否被访问 ,若存在未被访问点 即 任务不能完成 直接 输出未被覆盖点数量 结束程序
- 全部被访问到,贪心的思想 进行区间覆盖
详情见评测链接
代码及注释如下:
CPP#include <iostream>
#include <algorithm>
using namespace std;
const int INF = 1e9;
struct Zones
{
//用于dfs的结构体
int l , r;//此点能覆盖的 沙漠 区间
bool vis;//访问标记
}zone[510][510];
struct Lines
{
//用于 贪心区间覆盖 的结构体
int l , r;
}line[510];
int ans = 0 , desert = 0 , n , m;
// ans:若能完成任务所用水泵数量
// desert:不能覆盖数目
int high[510][510];//读入的高度
bool check(int a , int b , int x , int y)
{
//在dfs中 判断 能否进行搜索
if(high[a][b] <= high[x][y]) return 0;
if(x == 0 || x > n) return 0;
if(y == 0 || y > m) return 0;
return 1;
}
void change(int a , int b , int x , int y)
{
//在dfs中进行 修改可覆盖区间
zone[a][b].l = min(zone[a][b].l , zone[x][y].l);
zone[a][b].r = max(zone[a][b].r , zone[x][y].r);
}
void dfs(int x , int y)
{
zone[x][y].vis = 1;
if(x == n)
zone[x][y].l = zone[x][y].r = y;
else
zone[x][y].l = INF , zone[x][y].r = 0;
if(check(x , y , x - 1, y))
{
if(!zone[x - 1][y].vis)
dfs(x - 1, y);
change(x , y , x - 1 , y);
}
if(check(x , y , x + 1 , y))
{
if(!zone[x + 1][y].vis)
dfs(x + 1 , y);
change(x , y , x + 1 , y);
}
if(check(x , y , x , y - 1))
{
if(!zone[x][y - 1].vis)
dfs(x , y - 1);
change(x , y , x , y - 1);
}
if(check(x , y , x , y + 1))
{
if(!zone[x][y + 1].vis)
dfs(x , y + 1);
change(x , y , x , y + 1);
}
}
bool cmp(Lines a , Lines b)
{
if(a.l != b.l)
return a.l < b.l;
else
return a.r > b.r;
}
void GetAns()
{
//贪心覆盖
int last = 1 , next = 0;
for(int i = 1; i <= m; i++)
{
next = max(next , line[i].r);
if(line[i + 1].l > last)
ans++ , last = next;
if(last >= m) return;
}
}
int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <=m; j++)
{
cin >> high[i][j];
}
}
for(int i = 1; i <= m; i++)
{
dfs(1 , i);
line[i].l = zone[1][i].l;
line[i].r = zone[1][i].r;
}
for(int i = 1; i <= m; i++)
{
if(!zone[n][i].l)
desert++;
}
if(desert)
{
cout << 0 << endl << desert << endl;
return 0;
}
sort(line + 1 , line + m + 1 , cmp);
line[m + 1].l = INF;
GetAns();
cout << 1 << endl << ans << endl;
return 0;
}
回复
共 9 条回复,欢迎继续交流。
正在加载回复...