A
签到题,没什么好说的
int a,b; cin>>a>>b;
cout<<(a+b<=9? "Yes":"No")<<endl;
B
排序+二分
ll n,x; cin>>n>>x;
vector<ll>aa(n);
for(auto &i:aa) cin>>i;
std::sort(aa.begin(),aa.end());
if(x<aa[0]){
cout<<"0 "<<x<<endl; return 0;
}
int res=std::upper_bound(aa.begin(),aa.end(),x)-aa.begin();
cout<<res<<" "<<x-aa[res-1]<<endl;
C
比较有意思的一道题目。假设当前为
,我们在其后面加一个数字
,则
+
。因此我们只需要判断所有前缀为
之间整数的最小495的倍数即可,这个范围很小,以至于我们可以直接暴力
不知道为什么牛客
格式中加号'+'打不出来
ll n; cin>>n;
n%=495;
if(n==0){ cout<<"-1\n"; return 0; }
vector<int>dis(495);
int cnt=494, now=0;
while(cnt){
now+=495;
for(ll tt=now/10;tt;tt/=10){
if(tt<495&&!dis[tt]){
dis[tt]=now;
--cnt;
}
}
}
auto res=std::to_string(dis[n]);
cout<<res.substr(std::to_string(n).size(),114514)<<endl;
D
博弈,思维。题目内容不够多,至少应该说一下什么是字典序才对。
先手为了达到最优,会把小的字母尽可能删去(如果不删去的话那么后手一定有办法让这个字母为首字母)。考虑到后手希望字典序尽量小,在第一个字母相同的情况下肯定只保留一个字母。
举例来说,我们不妨假设后手拿到字符串bbacd
。显然此时后手最优一定是acd
。那么先手为了不达到这个结果,一定会优先把那个a
删去。其他情况同理。因此最后的结果一定是先手为了使字典序最优,直接自己把字符串删的只剩一位
int n; cin>>n;
std::string S; cin>>S;
cout<<std::max(S.front(),S.back())<<endl;
E
bfs,没有什么套路,就是注意bfs时一格一格地走(而不是走到不能走为止)
typedef long long ll;
typedef std::pair<int,int> PII;
PII operator+(PII x,PII y) {
return {x.first+y.first,x.second+y.second};
}
vector<PII>dir={{1,0},{0,1},{-1,0},{0,-1}};
#define y first
#define x second
void solve()
{
int n,m; cin>>n>>m;
vector<std::string>mart(n);
for(auto &i:mart) cin>>i;
PII S,T;
for(int i=0;i<n;++i) for(int j=0;j<m;++j){
if(mart[i][j]=='S') S={i,j};
else if(mart[i][j]=='T') T={i,j};
}
vector<vector<vector<int>>>vis(n,vector<vector<int>>(m,vector<int>(4,-1)));
std::queue<std::pair<PII,int>>q;
for(int i=0;i<4;++i){ q.emplace(S,i); vis[S.y][S.x][i]=0; }
while(q.size()){
auto [u,d]=q.front(); q.pop();
if(u==T){ vis[T.y][T.x][0]=vis[T.y][T.x][d]; break; }
if(mart[u.y][u.x]=='*'){
for(int k=0;k<4;++k){
vis[u.y][u.x][k]=vis[u.y][u.x][d];
auto v=u+dir[k];
if(v.y<0||v.x<0||v.y>=n||v.x>=m||~vis[v.y][v.x][k]) continue;
if(mart[v.y][v.x]=='#') continue;
vis[v.y][v.x][k]=vis[u.y][u.x][d]+1;
q.emplace(v,k);
}
}
else{
auto v=u+dir[d];
if(v.y<0||v.x<0||v.y>=n||v.x>=m||~vis[v.y][v.x][d]) continue;
if(mart[v.y][v.x]=='#') continue;
vis[v.y][v.x][d]=vis[u.y][u.x][d]+1;
q.emplace(v,d);
}
}
cout<<vis[T.y][T.x][0]<<endl;
}
#undef y
#undef x
F
状态压缩DP。对于 &运算到0 ,我们不是很好枚举,如果我们把原来所有的位数翻转,那么原问题相当于 |运算到所有位数为1,这是很好想的。我们只需要DP统计把所有位变成1所需的最少个数,那么
n-dp[255]
就是我们最终的答案
// 200,b = 11001000
// 255,b = 11111111
void solve()
{
int n; cin>>n;
int mask=(1<<8)-1, all=0;
vector<int>aa(n), dp(256,1e9);
for(auto &i:aa){
cin>>i;
i^=mask; all|=i;
for(int sub=i;sub;sub=(sub-1)&i) dp[sub]=1;
}
if(all<mask){
cout<<-1<<endl; return;
}
for(int i=1;i<256;++i){
if(dp[i]==1) continue;
for(int sub=i;sub;sub=(sub-1)&i) dp[i]=std::min(dp[i],dp[sub]+dp[i^sub]);
}
cout<<n-dp[255]<<endl;
}