Problem A. Matrix Game
A. Matrix Game
题意:给你有0和1的矩阵,0代表未被声明的点,1代表已声明的点,有两个人进行博弈,每个人每次只能选择未声明的点,并且未声明的点所在的行和列不能有已经声明的点。到最后,如果有一个人无法选取未声明的点,那么就代表他失败。最后答案输出获胜人的名字。
题解:统计出不包含1的行数和列数,最后取行列的最小值,也就是两个人博弈时能选取点的个数,如果整除2则第二个人赢,否则第一个人赢。
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <map>
#include <set>
#define inf (1LL<<62)-1
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double lb;
typedef pair<int, int> pii;
typedef unsigned long long ull;
const long double PI = acos(-1);
const int N = 5e3+10;
const int mod=998244353;
int a[55][55];
int hang[55],lie[55];
int main(int argc, char *argv[]) {
int t;
cin >> t;
while(t--)
{
memset(hang, 0, sizeof(hang));
memset(lie, 0, sizeof(lie));
int n,m;
cin >> n >> m;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++) cin >> a[i][j];
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
if(a[i][j])
{
hang[i]=1;
lie[j]=1;
}
}
int hh=0,li=0;
for(int i=0;i<n;i++)
if(hang[i]==0) hh++;
for(int i=0;i<m;i++)
if(lie[i]==0) li++;
if(min(hh,li)%2) cout << "Ashish" << endl;
else cout << "Vivek" << endl;
}
}
Problem B. Trouble Sort
B. Trouble Sort
题解:
如果b中存在两个不一样的类型,那么它们一定可以交换成非递减序列。
如果b里面类型一致,那么只有a为非递减才满足条件。
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <map>
#include <set>
#define inf (1LL<<62)-1
using namespace std;
extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double lb;
typedef pair<int, int> pii;
typedef unsigned long long ull;
const long double PI = acos(-1);
const int N = 5e3+10;
const int mod=998244353;
int a[505],b[505];
void solve()
{
int n;
cin >> n;int cnt1=0,cnt2=0;
for(int i=0;i<n;i++) cin >> a[i];
for(int i=0;i<n;i++)
{
cin >> b[i];
if(b[i]) cnt1=1;
else cnt2=1;
}
if(cnt1 && cnt2)
{
cout << "YES" << endl;
return ;
}
for(int i=1;i<n;i++)
{
if(a[i]<a[i-1])
{
cout << "NO" << endl;
return ;
}
}
cout << "YES" << endl;
}
int main(int argc, char *argv[]) {
int t;
cin >> t;
while(t--)
{
solve();
}
}
Problem C. Rotation Matching
C. Rotation Matching
题解:由题可知,如果直接暴力的话,时间复杂度为: O(n^2),所以得换一种思路。
将位移作为一种标准,即b数组每个数字移动到与a相同时所需的位移,最后统计相同位移出现次数最多的即答案。
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <map>
#include <set>
#define inf (1LL<<62)-1
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double lb;
typedef pair<int, int> pii;
typedef unsigned long long ull;
const long double PI = acos(-1);
const int N = 2e5+10;
const int mod=998244353;
int a[N],b[N],book[N];
map<int,int> mp;
int main(int argc, char *argv[]) {
int n;
cin >> n;
for(int i=0;i<n;i++) scanf("%d",&a[i]);
for(int i=0;i<n;i++) scanf("%d",&b[i]);
for(int i=0;i<n;i++) mp[a[i]]=i;
for(int i=0;i<n;i++) book[(i-mp[b[i]]+n)%n]++;
int ans=0;
for(int i=0;i<n;i++) ans=max(ans,book[i]);
cout << ans << endl;
}
Problem D. Solve The Maze
D. Solve The Maze
题解:
搜索题,但奈何自己的搜索过于菜,写了个记忆化搜索始终过不了,花了一天时间没搞出来。最后看题解才会了,感觉思路差不多,但“人家”的就是能过。
- 首先可以对一些“特殊情况”进行特判:
如果没有G,那么一定为Yes。
如果G和B相邻,那么一定为No。 - 接下来,先进行预处理,很明显将B的上下左右四个为“ . ”点封住是最优的,注意有可能将终点封住,所以需要特判,如果将终点封住则为No。然后从(n-1,m-1)终点进行dfs遍历,如果能遍历每一个G点,那么符合要求。否则No。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double ld;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
int nextp[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
char g[55][55];
bool flag;
int vis[55][55],cnt=0,n,m;
void dfs(int x,int y)
{
if(g[x][y]=='G')
cnt++;
for(int i=0;i<4;i++)
{
int tx=x+nextp[i][0];
int ty=y+nextp[i][1];
if(tx<0 || tx>=n || ty<0 || ty>=m) continue;
if((g[tx][ty]=='.' || g[tx][ty]=='G') && !vis[tx][ty])
{
vis[tx][ty]=1;
dfs(tx, ty);
}
}
}
void solve()
{
cnt=0;
cin >> n >> m;
for(int i=0;i<n;i++) cin >> g[i];
int num=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(g[i][j]=='G') num++;
if(g[i][j]=='B')
{
for(int k=0;k<4;k++)
{
int tx=i+nextp[k][0];
int ty=j+nextp[k][1];
if(tx<0 || tx>=n || ty<0 || ty>=m) continue;
if(g[tx][ty]=='G')
{
cout << "No" << endl;
return ;
}
if(g[tx][ty]=='.') g[tx][ty]='#';
}
}
}
}
if(!num)
{
cout << "Yes" << endl;
return ;
}
if(g[n-1][m-1]=='#')
{
cout << "No" << endl;
return ;
}
dfs(n-1, m-1);
if(cnt==num)
{
cout << "Yes" << endl;
return ;
}
cout << "No" << endl;
}
int main()
{
int t;
cin >> t;
while(t--)
{
memset(vis, 0, sizeof(vis));
solve();
}
}
Problem E. Maximum Subsequence Value
E. Maximum Subsequence Value
题解:由题可知,答案的结果就是选取这k个数的“或运算”结果。
- 当选取子序列个数≤3时,每个数都能选;
- 倘若个数大于3时,你必须选取已选3个数"或运算"结果二进制位为1的数,假如已选3个数"或运算"结果二进制位为11011,那么我就不能选第三位为1的数,因为已经有3个不满足条件,选中间一位为1,就不可能满足max(1,(k-2))条件。所以,只需在这些数中找任意三个数或运算结果最大的值即可,由于n不大,可以暴力解决。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define fi first
#define se second
#define pb push_back
#define pii pair<int,int>
ll a[505];
map<int,int>mp;
int main()
{
int n;
cin >> n;
for(int i=0;i<n;i++)
cin >> a[i];
ll ans=-1;
for(int i=0;i<n;i++)
for(int j=i;j<n;j++)
for(int k=j;k<n;k++)
ans=max(ans, (a[i]|a[j]|a[k]));
cout << ans << endl;
}
Problem F. Swaps Again
F. Swaps Again
题解:没想到F题也是个思维,但是不好想。
无论怎么交换,对称的两个数a[i]和a[n+1-i]永远是对称的,一一对应的。所以我们可以将(a[i]和a[n+1-i])打包,将b的(b[i]和b[n+1-i])打包,将这两个打包数组排序。最后判断是否一致即可。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define fi first
#define se second
#define pb push_back
#define pii pair<int,int>
int a[505],b[505];
vector<pair<int, int> >mp,mp1;
void solve()
{
mp.clear();
mp1.clear();
int n;
cin >> n;
for(int i=1;i<=n;i++) cin >> a[i];
for(int i=1;i<=n;i++) cin >> b[i];
if(n%2 && a[(n+1)/2]!=b[(n+1)/2])
{
cout << "No" << endl;
return ;
}
for(int i=1;i<=n/2;i++) mp.push_back(make_pair(min(a[i],a[n+1-i]),max(a[i],a[n+1-i])));
for(int i=1;i<=n/2;i++) mp1.push_back(make_pair(min(b[i],b[n+1-i]),max(b[i],b[n+1-i])));
sort(mp.begin(),mp.end());
sort(mp1.begin(),mp1.end());
for(int i=0;i<n/2;i++)
{
if(mp[i]!=mp1[i])
{
cout << "No" << endl;
return ;
}
}
cout << "YEs" << endl;
}
int main()
{
int t;
cin >> t;
while(t--)
{
solve();
}
}