C. Trapped in the Witch's Labyrinth
题目大意:给你一个设定好的迷宫,让你统计最多有多少个初始位置是走不出迷宫的
#1 成环的所有点都是走不出迷宫的
思路:可以考虑用记忆化搜索来搜每个点,&v = st[x,y],v 为-1时是能出迷宫的,v为0时代表该点还没被搜到,v为1时是不能走出迷宫的,v为2代表该点被搜过了但还没出结果,对于‘?’点,若能从四个方向搜到v为1或2的点说明可以构造成环,符合判断
代码:
void solve()
{
int n,m; cin >> n >> m;
vector<vector<char>> g(n+2,vector<char>(m+2));
vector<vector<int>> st(n+2,vector<int>(m+2,-1));
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
{
cin >> g[i][j];
st[i][j] = 0;
}
function<int(int,int)> dfs = [&](int x,int y) -> int
{
if (st[x][y] == -1) return -1;
if (st[x][y] == 1 || st[x][y] == 2) return 1;
st[x][y] = 2;
if (g[x][y] == 'U') st[x][y] = dfs(x-1,y);
else if (g[x][y] == 'R') st[x][y] = dfs(x,y+1);
else if (g[x][y] == 'L') st[x][y] = dfs(x,y-1);
else if (g[x][y] == 'D') st[x][y] = dfs(x+1,y);
else
{
if (dfs(x+1,y) == 1) st[x][y] = 1;
else if (dfs(x-1,y) == 1) st[x][y] = 1;
else if (dfs(x,y-1) == 1) st[x][y] = 1;
else if (dfs(x,y+1) == 1) st[x][y] = 1;
else st[x][y] = -1;
}
return st[x][y];
};
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
if (!st[i][j]) st[i][j] = dfs(i,j);
int ans = 0;
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
ans += st[i][j] == 1;
cout<<ans<<endl;
}
链接:Problem - 2034C - Codeforces
D. Robert Hood and Mrs Hood
题目大意:有一条长度为d的线段和一条有着多个小区间的大区间,请你输出能覆盖到最多和最少的区间的位置
思路:一眼差分
代码:
void solve()
{
int n,d,k;
cin >> n >> d >> k;
vector<i64> v(n+2);
while (k--)
{
int l,r; cin >> l >> r;
v[max(1,l-d+1)] ++ ;
v[r+1] -- ;
}
for (int i = 1; i <= n; i ++ )
v[i] += v[i-1];
int m1 = 1, m2 = 1;
i64 mn = 1e9, mx = -1;
for (int i = 1; i + d - 1 <= n; i ++ )
{
if (v[i] > mx) mx = v[i],m2 = i;
if (v[i] < mn) mn = v[i],m1 = i;
}
cout<<m2<<" "<<m1<<endl;
}
链接:Problem - 2014D - Codeforces
E. Klee's SUPER DUPER LARGE Array!!!
题目大意:给出一段n,n+1到n+k-1的一段连续的数组,让你求出a1+a2+……+ai-a(i+1)-……-a(n)的最小绝对值
思路:令x = a1加到ai,y = ai+1加到an,那么无非就是x <= y 和 x > y两种情况,数据范围很大,直接二分下标即可
代码:
void solve()
{
i64 n,k;
cin >> n >> k;
i64 sum = (k + k + n - 1) * n / 2;
i64 l = 0, r = n;
while (l < r)
{
i64 mid = (l + r + 1) >> 1;
i64 res = (k + k + mid - 1) * mid / 2;
if (res <= sum - res) l = mid;
else r = mid - 1;
}
cout<<min(abs(sum - 2 * (k + k + l - 1) * l / 2), abs(sum - 2 * (k + k + l) * (l + 1) / 2) )<<endl;
}