PREFACE:
本人菜鸡,只能把简单题补了,本文章没有EJKL
这场人好少,牛客多校之后没人了,没兴致打了说是
A.装备二选一(一)
假设攻击一百次,计算出100次的总伤害
void solve(){
int a,b,c,d;
cin>>a>>b>>c>>d;
ll ans1 = (100-a)*1+a*b;
ll ans2 = (100-c)*1+c*d;
if(ans1>=ans2){
cout<<"NO"<<endl;
}else{
cout<<"YES"<<endl;
}
}
F-追寻光的方向
倒序扫一遍数组求一个递增的序列,然后双指针扫一遍看有几个数字就行了
void solve(){
int n;
cin>>n;
vector<int> a(n+1);
for(int i = 1;i<=n;i++) cin>>a[i];
for(int i = n-1;i>=1;i--){
a[i] = max(a[i],a[i+1]);
}
int ans = 0;
for(int i = 1;i<=n;i++){
int j = i;
if(a[j]==a[j+1]&&j+1<=n){
while(a[j]==a[j+1]&&j+1<=n) j++;
ans++;
i = j;
}else{
ans++;
}
}
cout<<ans-1<<endl;
}
B-百变马楼
纯大暴力,无敌了模拟,wa了两发把两种特判加上就对了,普通情况就是双指针,特殊情况形如aab和aaab,eeee和eeeee
void solve(){
string a;
string b;
cin>>a>>b;
int len = a.size();
int posi = len-1;
for(int i = 0;i<len;i++){
if(a[i]!=b[i]){
if(a[i]!=b[i+1]){
cout<<"0";
return ;
}
}
}
char st = a[0];
bool sucsta = false;
bool sucstb = false;
for(int i = 0;i<=len;i++){
if(b[i]!=st) break;
if(i==len){
sucstb= true;
}
}
for(int i = 0;i<len;i++){
if(a[i]!=st) break;
if(i==len-1){
sucsta = true;
}
}
if(sucsta&&sucstb){
cout<<len+1<<endl;
for(int i = 0;i<=len;i++){
cout<<i<<' '<<st<<endl;
}
return ;
}
for(int i = 0;i<len;i++){
if(a[i]==b[i]){
if(i==len-1){
cout<<1<<endl<<len<<' '<<b[len];
return ;
}
}else{
break;
}
}
for(int i = 0;i<len;i++){
if(a[i]!=b[i]){
posi = i;
break;
}
}
char ans = b[posi];
// posi++;
int j = posi;
if(b[j]==b[j-1]&&j-1>=0){
while(b[j]==b[j-1]&&j-1>=0) j--;
}
cout<<posi-j+1<<endl;
for(int i = j;i<=posi;i++){
cout<<i<<' '<<ans<<endl;
}
}
I-正义从不打背身
照例手玩,手玩后发现是奇数递减后偶数递增或者偶数递减后奇数递增,和m的奇偶有关,并且每一位的操作数是m-i+1次,所以很简单的手玩(用st来表示每个位置的状态,再先处理每一位m次之后的状态,最后确定位置)
const int N = 2e6+10;
int st[N];
int ans[N];
int idx = 1;
void solve(){
int n,m;
cin>>n>>m;
// vector<int> st(n+1);
st[0] = 0;
string a;
cin>>a;
for(int i = 1;i<=n;i++){
if(a[i-1]=='P'){
st[i] = 0;
}else{
st[i] = 1;
}
}
for(int i = 1;i<=m;i++){
int cnt = m-i+1;
if(cnt%2==0){
;
}else{
st[i] = st[i]^1;
}
}
if(m%2==1){
for(int i = m;i>=1;i-=2) ans[idx] = st[i],idx++;
for(int i = 2;i<=m-1;i+=2) ans[idx] = st[i],idx++;
for(int i = m+1;i<=n;i++) ans[idx] = st[i],idx++;
}else{
for(int i = m;i>=2;i-=2) ans[idx] = st[i],idx++;
for(int i = 1;i<=m-1;i+=2) ans[idx] = st[i],idx++;
for(int i = m+1;i<=n;i++) ans[idx] = st[i],idx++;
}
for(int i = 1;i<=n;i++){
cout<<(ans[i]^1)<<' ';
}
}
D-四散而逃
wa一发后首先发现跟两边的数字没有任何关系,并且中间的数字不能是全为奇数,所以要至少有一个偶数,所以可以得到先把偶数分给奇数使奇数变为偶数然后再让奇数逃走,并且还发现,只要有一个偶数就行了,因为1可以传递,所以偶数的逃逸次数是(x/2)奇数的逃逸次数就是(x+1)/2;
void solve(){
int n;
cin>>n;
vector<int> a(n+4);
for(int i = 1;i<=n;i++){
cin>>a[i];
}
int ans = 0;
bool f = 0;
for(int i = 2;i<=n-1;i++){
if(a[i] > 1) f = 1;
ans += (a[i]+1)/2;
}
if(n == 3 && a[2]%2) f = 0;
if(f) cout<<ans<<endl;
else cout<<"-1\n";
}
C 16进制世界
一开始想的是直接01背包套下判断条件,就是dp[i-1][j]是16倍数那么考虑不加入第n个物品
如果(dp[i-1][j-v[i]]+w[i])%16==0,那么就加入,最后算出最大dp值然后记录路径输出就好了,
怒wa一发,手玩2 1 2 15 直接错了
//WA
const int N = 1e5+10;
int v[N];
int w[N];
void solve(){
int n,m;
cin>>n>>m;
int dp[n+1][m+1];
int p[n+1][m+1];
memset(dp,0,sizeof(dp));
memset(p,0,sizeof(p));
for(int i = 1;i<=n;i++){
cin>>v[i]>>w[i];
}
for(int i = 1;i<=n;i++){
for(int j = 0;j<=m;j++){
dp[i][j] = dp[i-1][j];
if(j>=v[i]&&(dp[i-1][j-v[i]]+w[i])%16==0){
dp[i][j] = max(dp[i][j],dp[i-1][j-v[i]]+w[i]);
p[i][j] = 1;
}
}
}
int ans = 0;
int i=n,j=m;
while(i>=0&&j>=0){
if(p[i][j])
{
ans++;
j-=v[i];
}
i--;
}
cout<<ans<<endl;
}
赛后看大佬的代码都是取模运算,直接粘官方题解吧,出自官方题解
G-等公交车
我们在距离为 dd 的车站在 tt 时刻开始等候,其实就相当于我们在距离为 00 的车站在 t−d 时刻开始等候。因为一辆车在某个时间到距离为 d 的车站,那么在 d 分钟前一定到距离为 0 的车站,所以两者的到站顺序是完全一致的,所以直接对t-d二分就行了
const int N = 1e5+10;
int d[N],t[N];
void solve(){
int n,m;
cin>>n>>m;
for(int i = 1;i<=n;i++) cin>>d[i];
for(int j = 1;j<=m;j++) cin>>t[j];
int q;
cin>>q;
while(q--){
int tt,x;
cin>>tt>>x;
tt-=d[x];
auto iter = lower_bound(t+1,t+1+m,tt);
if(iter-t>m)cout<<"TNT"<<endl;
else cout<<*iter-tt<<endl;
}
}
H-24点
纯纯是来攻击代码能力了,菜鸡不会,建议看题解官方题解