D.思维题:
若按照顺序发现很难入手,于是我们不妨先小紫,再让小红反悔即可
假设为cabababbabazbc,如果直接小紫,那么它一定以a开头,于是小红可以先把首尾的a去掉,即czbc,此时可以得到bc,于是小红把b也删了,这样小紫只可以取c了。
最小值在两边呢?
对于aba,小红无论怎么删,小紫都可以得到a,因此,我们可以得到一个结论:
若两边的字母一样,答案就是那个字母。
那么若不一样呢?
我们看看abc,对于小紫,可以变成a,于是小红一定要删了 a,同理也会把b删了,答案就是C.
假如两边没有min,dbhfncac,那么小红一定删bhfnca,此时d>c,所以答案是d.
假如两边有一个是abcddsagbw,于是小红让其变成gbw,此时小紫可以bw,于是把gb也删了,得到w.
因此,我们可以得出一个结论:答案就是较大的那一个。
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
string s;
int n;
int main(){
cin>>n>>s;
if(n==1) cout<<s;
else{
if(s[0]>=s[n-1]) cout<<s[0];
else cout<<s[n-1];
}
}
E.分层BFS
我们可以分成4个图,dis[1010][1010][4],在每一个图中只能走一个方向。当他遇到*可以走到其他图
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
int t,n,m,dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}},tx,ty;
string s[1010];
int dis[1002][1010][4];
struct node{
int x,y,k;
};
queue<node> q;
int main(){
cin>>t;
while(t--){
cin>>n>>m;
for(int i=0;i<n;i++) cin>>s[i];
/* for(int i=0;i<n;i++) cout<<s[i]<<endl;*/
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
for(int k=0;k<4;k++) dis[i][j][k]=1e9;
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(s[i][j]=='S'){
for(int k=0;k<4;k++){
q.push({i,j,k});
dis[i][j][k]=0;
}
}
if(s[i][j]=='T'){
tx=i;
ty=j;
}
}
}
while(!q.empty()){
node ck=q.front();
q.pop();
int x=ck.x,y=ck.y;
if(s[x][y]=='.'||s[x][y]=='S'||s[x][y]=='T'){
int xx=x+dir[ck.k][0],yy=y+dir[ck.k][1];
if(xx<0||yy<0||xx>=n||yy>=m||s[xx][yy]=='#') continue;
if(dis[xx][yy][ck.k]>dis[x][y][ck.k]+1){
dis[xx][yy][ck.k]=dis[x][y][ck.k]+1;
q.push({xx,yy,ck.k});
}
}
else if(s[x][y]=='*'){
for(int i=0;i<4;i++){
if((i^(ck.k))==1) continue;
int xx=x+dir[i][0],yy=y+dir[i][1];
if(xx<0||yy<0||xx>=n||yy>=m||s[xx][yy]=='#') continue;
if(dis[xx][yy][i]>dis[x][y][ck.k]+1){
dis[xx][yy][i]=dis[x][y][ck.k]+1;
q.push({xx,yy,i});
}
}
}
}
int mi=1e9;
for(int i=0;i<4;i++) mi=min(mi,dis[tx][ty][i]);
if(mi>=1e9) cout<<-1<<endl;
else cout<<mi<<endl;
}
}
F。DP
本质上就是求一个最短的位与==0的子序列。
首先看到数据范围先去重,因为相同的&还是自己。
接下来我们令dp[i][0]表示原来的合成i的最小保留,1代表现在,不断滚动即可。
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
int t,n,dp[210][2],x;
bool tong[200];
int main(){
cin>>t;
while(t--){
cin>>n;
memset(tong,0,sizeof(tong));
memset(dp,0x3f,sizeof(dp));
for(int i=0;i<n;i++){
scanf("%d",&x);
tong[x]=1;
}
for(int i=0;i<=200;i++){
if(tong[i]==0) continue;
dp[i][1]=1;
for(int j=0;j<=200;j++){
dp[i&j][1]=min(dp[i&j][1],dp[j][0]+1);
}
for(int j=0;j<=200;j++) dp[j][0]=dp[j][1];
}
if(dp[0][0]>n) cout<<-1<<endl;
else cout<<n-dp[0][0]<<endl;
}
}