题意:给出n*m的网格,只有当前格子的一整行和一整列都为0时,这个格子才能被翻成1。最后没有格子翻的人则输掉。求谁赢。
题记:可以放的棋子取所有空行和空列中的最小值,棋子数量余是奇数则Ashish赢,否则Vivek赢。
#include
using namespace std;
const int N=60;
int row[N],col[N];
int main(){
int T;
cin>>T;
while(T--){
memset(row,0,sizeof(row));
memset(col,0,sizeof(col));
int n,m;
cin>>n>>m;
int x;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
cin>>x;
if(x==1){
row[i]=1;
col[j]=1;
}
}
int sum=0,sum1=0,sum2=0;
for(int i=1;i<=n;i++)
if(!row[i])
sum1++;
for(int i=1;i<=m;i++)
if(!col[i])
sum2++;
sum=min(sum1,sum2);
if(sum%2==1) cout<<"Ashish"<<endl;
else cout<<"Vivek"<<endl;
}
return 0;
}
题意:有两种类型的数,不同类型的数位置可以互相调换,求最后能不能变成一个递增的数列。
题记:首先判断一下原数组是否有序的,如果原数组无序且都是同一类型则不符合条件。
#include
using namespace std;
const int N=550;
int a[N],b[N];
int main(){
int T;
cin>>T;
while(T--){
int n;
cin>>n;
bool flag=true;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]<a[i-1])
flag=false;
}
for(int i=1;i<=n;i++){
cin>>b[i];
if(i!=1&&b[i]!=b[i-1])
flag=true;
}
if(flag)puts("Yes");
else puts("No");
}
return 0;
}
题意:将b数组以一定方式移动(略),使得b与a相同位置的相同数组最多。
题记:先记录下a数组中每个数的位置,然后遍历b数组记录下当前b数组中的数和a数组中相同数的距离,最后距离个数相同最多的即答案。
#include
using namespace std;
const int N=2e5+10;
int a[N],b[N],pos[N],t[N];
bool cmp(int x,int y){
return x>y;
}
int main(){
int n;
cin>>n;
int pos1,pos2;
for(int i=1;i<=n;i++){
cin>>a[i];
pos[a[i]]=i;
}
int x;
for(int i=1;i<=n;i++){
cin>>x;
if(pos[x]>=i)
t[pos[x]-i]++;
else
t[pos[x]-i+n]++;
}
sort(t,t+n,cmp);
cout<<t[0]<<endl;
return 0;
}
题意:n*m的网格,终点是(n,m),问所有好人能不能都到达终点。
题记:从终点开始bfs,看一下能不能找到所有好人即可。注意坏人的上下左右都不能走(要堵住)。
#include
using namespace std;
typedef pair<int,int> PII;
const int N=55;
char a[N][N];
bool vis[N][N];
int dis[4][2]={1,0,0,1,-1,0,0,-1};
int n,m;
bool check(int x,int y){
if(x<1||x>n||y<1||y>m||a[x][y]=='B'||a[x][y]=='#'||vis[x][y])
return false;
for(int i=0;i<4;i++){
int dx=x+dis[i][0];
int dy=y+dis[i][1];
if(dx>=1&&dx<=n&&dy>=1&&dy<=m&&a[dx][dy]=='B')
return false;
}
return true;
}
int bfs(int x,int y){
memset(vis,0,sizeof(vis));
if(!check(x,y))
return 0;
vis[x][y]=true;
int ans=0;
queue<PII>q;
q.push({x,y});
while(!q.empty()){
PII st=q.front();
q.pop();
PII ne;
for(int i=0;i<4;i++){
ne.first=st.first+dis[i][0];
ne.second=st.second+dis[i][1];
if(check(ne.first,ne.second)){
if(a[ne.first][ne.second]=='G')
ans++;
q.push(ne);
vis[ne.first][ne.second]=true;
}
}
}
return ans;
}
int main(){
int T;
cin>>T;
while(T--){
cin>>n>>m;
int sum=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
cin>>a[i][j];
if(a[i][j]=='G')
sum++;
}
//cout<
if(bfs(n,m)==sum)
puts("Yes");
else
puts("No");
}
return 0;
}
题意:取一个长度为k的子序列,子序列的值表示为子序列中每个数的二进制位至少用到max(1,k-2)次。
题记:当k<=3时有最优解(具体证明不大会),所有只需要考虑k<=3的情况即可。
#include
using namespace std;
typedef long long ll;
const int N=510;
ll a[N];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
ll ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
ans=max(ans,a[i]|a[j]|a[k]);
cout<<ans<<endl;
return 0;
}