A
题意:Alice和Bob轮流改变字符串,Alice先手,每次改变可以选择未被改变过的位置改成除原字符外的任意字符,Alice想让字典序尽可能小,Bob想让字典序尽可能大,问最后的字符串
思路:Alice一定是选靠前的位置改成字典序小的字母,Bob也是选择靠前的位置改成字典序大的字母,所以从前往后,Alice与Bob交替更改。
#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
#define endl '\n'
#define sf(x) scanf("%d",&x)
#define rep(i,x) for(i=0;i<(x);i++)
#define gen(x) x##_
#define ios std::ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;
using namespace std;
string s;
void solve()
{
s.clear();
cin>>s;
int len=s.length();
for(int i=0;i<len;i++)
{
if(i&1)
{
if(s[i]=='z') s[i]='y';
else s[i]='z';
}
else
{
if(s[i]=='a') s[i]='b';
else s[i]='a';
}
}
cout<<s<<'\n';
}
int main()
{
//ios;
int _t=1;
cin>>_t;
while(_t--)
{
solve();
}
system("pause");
return 0;
}
B
题意:英雄初始的攻击力A,生命值B,n个怪兽及每个怪兽的攻击力a[i],生命值b[i]。每次战斗英雄的生命值变为B-a[i],怪的生命值变为b[i]-A。对每个怪可以发动多次战斗。若英雄能打死全部怪兽(即使最后英雄也死去)则输出YES,否则输出NO
思路:因为英雄受到的总伤害是不变的,可以先计算出总伤害为sa,如果sa<=B,显然输出YES;如果sa>B,则需要讨论英雄在被杀的时候,是否可以杀死最后一只怪物,当存在sa-a[k]<B,则在击杀第k只怪时,是可以完成一换一的。即只需当sa-maxa<B,就输出YES。否则NO
#include <bits/stdc++.h>
#define lowbit(x) x &(-x)
#define endl '\n'
#define sf(x) scanf("%d", &x)
#define rep(i, x) for (i = 0; i < (x); i++)
#define gen(x) x##_
#define ios \
std::ios::sync_with_stdio(false); \
cin.tie(0), cout.tie(0)
#define PII pair<int, int>
typedef long long ll;
const int N = 1e5 + 10;
const int inf = 0x3f3f3f3f;
using namespace std;
struct node
{
ll a, b;
} m[N];
ll A, B, n;
void solve()
{
//memset(m,0,sizeof m);
//cin >> A >> B >> n;
scanf("%lld %lld %lld",&A,&B,&n);
for (int i = 1; i <= n; i++)
scanf("%lld",&m[i].a);
//cin >> m[i].a;
for (int i = 1; i <= n; i++)
scanf("%lld",&m[i].b);
//cin >> m[i].b;
ll sa=0,amax=0;
for (int i = 1; i <= n; i++)
{
ll t = (m[i].b +A-1)/ A; //t为轮数m[i].b/A向上取整
sa+=t*m[i].a;
amax=max(m[i].a,amax);
}
if(sa-amax>=B) cout<<"NO\n";
else cout<<"YES\n";
}
int main()
{
// ios;
int _t = 1;
cin >> _t;
while (_t--)
{
solve();
}
system("pause");
return 0;
}
C
题意:交互题,有一个长度为n的数组,其中存放着1~n的全排列。让你在100次询问之内找到局部最小值。最初只知道数组的大小,数组每个位置上的值需要通过询问得到
若ai为局部最小值,&&
思路:起初&&
,若我们在二分的时候能维护住这个性质,则二分到l=r时,这个点就满足比两边小。
若a[mid]<a[mid+1],则[l,mid]仍满足这个性质。
若a[mid]>a[mid+1],则[mid+1,r]仍满足这个性质。
所以我们总能维护满足性质的区间,时间复杂度为log(2)n
#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
#define endl '\n'
#define sf(x) scanf("%d",&x)
#define rep(i,x) for(i=0;i<(x);i++)
#define gen(x) x##_
#define ios std::ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e5+10;
const int inf=0x3f3f3f3f;
using namespace std;
int a[N];
int n;
void get(int x)
{
if(x>n||x<1||a[x]) return ;
cout<<"? "<<x<<'\n';
fflush(stdout);
cin>>a[x];
}
void solve()
{
cin>>n;
a[0]=1e9,a[n+1]=1e9;
int l=1,r=n;
while(l<r)
{
int mid=l+r>>1;
get(mid);get(mid+1);
if(a[mid]<a[mid+1]) r=mid;
else l=mid+1;
}
cout<<"! "<<l<<'\n';
}
int main()
{
//ios;
int _t=1;
//cin>>_t;
while(_t--)
{
solve();
}
system("pause");
return 0;
}