A.Matrix Game
#include <bits/stdc++.h>
using namespace std;
const int N = 51;
int n, m;
int a[N][N];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin >> t;
while (t--)
{
cin >> n >> m;
set<int> r, c;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cin >> a[i][j];
if (a[i][j] == 1)
r.insert(i), c.insert(j);
}
}
int mn = min(n - r.size(), m - c.size());
if (mn % 2)
cout << "Ashish" << '\n';
else
cout << "Vivek" << '\n';
}
return 0;
}
B.Trouble Sort
#include<iostream>
#include<cstdio>
using namespace std;
int T,n,m,s[1010];
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
int f=0,l=0,y=0;
for(int i=1;i<=n;i++) {
scanf("%d",&s[i]);
if(s[i]<s[i-1]) f=1;
}
for(int i=1;i<=n;i++) {
scanf("%d",&s[i]);
if(s[i]==0) l=1;
else y=1;
}
if(l+y==1&&f==1) puts("No");
else puts("Yes");
}
return 0;
}
C.Rotation Matching
思路: 我们将a数组不动,移动b数组。题目中只要求最大匹配数,无需管移动步数。因此我们取向左为正方向(左移1步<----->右移-1步),然后计算数组a,b每个数位置的差值,找到差最大即为答案
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int a[N], b[N], aa[N], bb[N], ans[N];
int n;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
aa[a[i]] = i;
}
for (int i = 1; i <= n; i++)
{
cin >> b[i];
bb[b[i]] = i;
ans[(bb[b[i]] - aa[b[i]] + n) % n]++;//统计距离
/*
我们一点点剥析,
bb[b[i]]-aa[b[i]] 即使计算他们的距离差
(bb[b[i]]-aa[b[i]]+n)%n ,由于减出来可能是负数,所以要加上n,那该如
何消n呢,在模一下n就好了
*/
}
sort(ans, ans + n + 1);//排序算最大
cout << ans[n];//最大即是答案
return 0;
}
/*
sort排序函数的使用方法
sort(起始地址,结束地址(不包含))
*/
D.Solve The Maze
分析:DFS
#include <bits/stdc++.h>
using namespace std;
const int N = 100;
char mp[N][N];
int vis[100][100];//标记该格子是否被走过
int tag[100][100];//标记该格子是否被遍历过
int flag, T;
int n, m;
void dfs(int x, int y)
{
if (x < 1 || x > n || y < 1 || y > m)
return;
if (mp[x][y] == '#')
return;
if (mp[x][y] == 'G' || mp[x][y] == 'B')
tag[x][y] = 1;
int xx[4] = {-1, 1, 0, 0}, yy[4] = {0, 0, 1, -1};
for (int i = 0; i < 4; i++)
{
if (!vis[x + xx[i]][y + yy[i]])
{
vis[x + xx[i]][y + yy[i]] = 1;
dfs(x + xx[i], y + yy[i]);
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> T;
while (T--)
{
cin >> n >> m;
memset(vis, 0, sizeof(vis));//初始化
memset(tag, 0, sizeof(tag));//初始化
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> mp[i][j];
bool flag = true;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
if (mp[i][j] == 'B')
{
if (mp[i + 1][j] == '.')
mp[i + 1][j] = '#';
if (mp[i - 1][j] == '.')
mp[i - 1][j] = '#';
if (mp[i][j + 1] == '.')
mp[i][j + 1] = '#';
if (mp[i][j - 1] == '.')
mp[i][j - 1] = '#';
}
}
vis[n][m] = 1;
dfs(n, m);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (mp[i][j] == 'G')
{
if (tag[i][j])
continue;
else
{
flag = false;
break;
}
}
if (mp[i][j] == 'B')
{
if (tag[i][j])
{
flag = false;
}
}
}
if (!flag)
break;
}
if (flag)
cout << "Yes" << '\n';
else
cout << "No" << '\n';
}
return 0;
}
【DFS笔记】什么时候需要回溯?什么时候不需要回溯?
什么时候需要回溯:
DFS的本质是每一步做选择,当这个选择可做可不做(比如迷宫,这一步可以走,也可以不走),要在递归之后回溯
什么时候不需要回溯:
当遇到一个选择时,一定要对它操作时,那么就不需要回溯。比如要标记求所有情况,找到了就要标记。如果取消标记,那么就会重复计算。