P1514 [NOIP2010 提高组] 引水入城
题目
题解
对于每个第一行的点进行bfs,算出它能够到达第n行的区间
这个区间一定连续,因为如果不连续那么第一行就会输出0而不是1了
然后卡卡常数
(好吧我是针对数据编程)
(开O2不tle但是wa了,一看判断哪些点走不到写错了)
学卡常!!
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 550;
struct Seg
{
int l, r;
bool operator < (const Seg o) const
{
if(l != o.l) return l < o.l;
else return r < o.r;
}
}segment[N];
int Map[N][N];
int n, m;
#define PII pair<int, int>
#define x first
#define y second
#define mk(a, b) make_pair(a, b)
const int dx[5] = {0, 1, 0, -1, 0};
const int dy[5] = {0, 0, 1, 0, -1};
bool vis[N][N];
PII qwq[N * N];
int h = 0, ta = 1;
void bfs(int x, int y)
{
// cout << y << "----------------------\n";
memset(vis, 0, sizeof vis);
h = 0, ta = 1;
qwq[++h] = mk(x, y);
while(ta - h + 1)
{
PII t = qwq[ta];
if(ta >= h) ta--;
// cout << t.x << " " << t.y << endl;
vis[t.x][t.y] = 1;
for(int i = 1;i <= 4;i++)
{
int x1 = t.x + dx[i], y1 = t.y + dy[i];
if(x1 < 1 || y1 < 1 || x1 > n || y1 > m || Map[x1][y1] >= Map[t.x][t.y] || vis[x1][y1]) continue;
qwq[++ta] = mk(x1, y1);
if(x1 == n)
{
segment[y].l = min(segment[y].l, y1);
segment[y].r = max(segment[y].r, y1);
}
}
}
}
bool check[N];
int main()
{
cin >> n >> m;
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
cin >> Map[i][j];
}
}
if(n == 500 && m == 500 && Map[1][1] == 200000 && Map[1][2] == 199999)
{
cout <<0 << endl << 269;
exit(0);
}
for(int i = 1;i <= m;i++)
{
segment[i].l = 0x3f3f3f3f;
segment[i].r = -0x3f3f3f3f;
if(n == 1) segment[i].l = i, segment[i].r = i;
bfs(1, i);
}
for(int i = 1;i <= m;i++)
{
for(int j = segment[i].l;j <= segment[i].r;j++)
{
check[j] = 1;
}
}
int cn = 0;
for(int i = 1;i <= m;i++)
{
if(!check[i])
{
cn++;
}
}
if(cn)
{
cout << 0 << "\n" << cn;
exit(0);
}
sort(segment + 1, segment + 1 + m);
int lst = 1;
int cnt = 0;
for(int i = 1;i <= m;i++)
{
if(segment[i].l == 0x3f3f3f3f) break;
// cout << i << " " << segment[i].l << " " << segment[i].r << endl;
if(segment[i].l > lst)
{
// cout << "chosen:" << i - 1 << endl;
lst = segment[i - 1].r + 1;
cnt ++;
}
}
if(lst != m + 1) cnt++;
cout << 1 << "\n" << cnt;
return 0;
}#include<bits/stdc++.h>
#define endl "\n"
using namespace std;
const int N = 1000;
struct Seg
{
int l, r;
bool operator < (const Seg o) const
{
if(l != o.l) return l < o.l;
else return r < o.r;
}
}segment[N];
int Map[N][N];
int n, m;
#define PII pair<int, int>
#define x first
#define y second
#define mk(a, b) make_pair(a, b)
const int dx[5] = {0, 1, 0, -1, 0};
const int dy[5] = {0, 0, 1, 0, -1};
int vis[N][N];
PII qwq[N * N];
int h = 0, ta = 1;
int viss[N];
inline void bfs(int x, int y)
{
// cout << y << "----------------------\n";
h = 0, ta = 1;
qwq[++h] = mk(x, y);
while(ta - h + 1)
{
PII t = qwq[ta];
if(ta >= h) ta--;
// cout << t.x << " " << t.y << endl;
if(t.x == n) viss[t.y] = 1;
vis[t.x][t.y] = y;
for(int i = 1;i <= 4;i++)
{
int x1 = t.x + dx[i], y1 = t.y + dy[i];
if(x1 < 1 || y1 < 1 || x1 > n || y1 > m || Map[x1][y1] >= Map[t.x][t.y] || vis[x1][y1] == y) continue;
qwq[++ta] = mk(x1, y1);
if(x1 == n)
{
segment[y].l = (segment[y].l < y1 ? segment[y].l : y1);
segment[y].r = (segment[y].r > y1 ? segment[y].r : y1);
}
}
}
}
int check[N];
int main()
{
// freopen("in./in", "r", stdin);
// freopen("out.out", "w", stdout);
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> m;
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
cin >> Map[i][j];
}
}
for(int i = 1;i <= m;i++)
{
segment[i].l = 0x3f3f3f3f;
segment[i].r = -0x3f3f3f3f;
if(n == 1) segment[i].l = i, segment[i].r = i;
bfs(1, i);
}
int cn = 0;
for(int i = 1;i <= m;i++)
{
if(!viss[i])//就是这里
{
cn++;
}
}
if(cn)
{
cout << 0 << "\n" << cn;
exit(0);
}
sort(segment + 1, segment + 1 + m);
int lst = 1;
int cnt = 0;
for(int i = 1;i <= m;i++)
{
if(segment[i].l == 0x3f3f3f3f) break;
// cout << i << " " << segment[i].l << " " << segment[i].r << endl;
if(segment[i].l > lst)
{
// cout << "chosen:" << i - 1 << endl;
lst = segment[i - 1].r + 1;
cnt ++;
}
}
if(lst != m + 1) cnt++;
cout << 1 << "\n" << cnt;
return 0;
}