A. Anti-knapsack

贪心

大概思路

让你求 $1$ 到 $n$ 的最大集合,使的任意子集元素之和不为 $k$。

显然, $k+1$ 到 $n$ 的元素都能加进来,$k$ 本身不能加进来,$\lfloor\frac{k}{2}\rfloor$ 到 $k-1$ 可以加进来,构造完毕,直接输出集合大小和元素即可。

参考代码

void solve() {
    cin(n);cin(k);
    cout<<n-k+k/2<<et;
    rep(i,(k+1)/2,k-1)cout<<i<<" ";
    rep(i,k+1,n)cout<<i<<" ";
    cout<<et;
}

B. Planet Lapituletti

模拟

大概思路

问你在某种时间进制下,找到从当前时刻到未来,最近一次使7段字显示器显示的时间镜像后仍为合法时间的时刻并输出。

直接暴力往后递增时间,找到符合题意的时间就直接输出即可。

参考代码

int h,m;

int mp[10]={0,1,5,-1,-1,2,-1,-1,8,-1};
//其实还有一种写法,把这里的-1全换成9999,这样的话,只要任何一个数位不合法,ck函数里的ni和nj至少有一个会被污染成非法数,这样可以在ck里少写几行特判:

// int mp[10]={0,1,5,9999,9999,2,9999,9999,8,9999};
// bool ck(int i,int j){
//     int ni=10*(mp[j%10])+mp[j/10];
//     int nj=10*(mp[i%10])+mp[i/10];
//     if(ni>=h||nj>=m)return 0;
//     return 1;
// }

bool ck(int i,int j){
    //cout<<i<<" "<<j<<"]";
    int ni=0,nj=0;
    if(i<10){if(mp[i]==-1)return 0;}
    else if(mp[i%10]==-1||mp[i/10]==-1)return 0;

    if(j<10){if(mp[j]==-1)return 0;}
    else if(mp[j%10]==-1||mp[j/10]==-1)return 0;

    ni=10*(mp[j%10])+mp[j/10];
    nj=10*(mp[i%10])+mp[i/10];
    if(ni>=h||nj>=m)return 0;
    return 1;
}

pair<int,int> nxt(int i,int j){
    j++;
    if(j>=m){j=0;i++;}
    if(i>=h)i=0;
    return {i,j};
}

void print(int i,int j){
    cout<<(i/10)<<(i%10)<<":"<<(j/10)<<(j%10)<<et;
}

void solve() {
    cin>>h>>m;
    scin(s);
    int nowh=s[0]-'0',nowm=s[3]-'0';
    nowh=nowh*10+s[1]-'0';
    nowm=nowm*10+s[4]-'0';
    while(!ck(nowh,nowm)){
        auto t=nxt(nowh,nowm);
        nowh=t.first;
        nowm=t.second;
    }
    print(nowh,nowm);
}

来自某✌的码:

int cal(int a) {
  if (a == 2) return 5;
  if (a == 5) return 2;
  return a;
}
int a[5] = {0, 1, 2, 5, 8};
void huangyu() {
  int h = read(), m = read();
  ll hh, mm;
  cin >> hh;
  getchar();
  cin >> mm;
  for (int i = 0; i < 5; i++)
    for (int j = 0; j < 5; j++)
      for (int k = 0; k < 5; k++)
        for (int l = 0; l < 5; l++) {
          if (a[i] * 10 + a[j] < h && a[k] * 10 + a[l] < m)
            if ((a[i] * 10 + a[j]) * m + (a[k] * 10 + a[l]) >= (hh * m + mm))
              if ((cal(a[l]) * 10 + cal(a[k])) < h &&
                  ((cal(a[j]) * 10 + cal(a[i])) < m)) {
                cout << a[i] << a[j] << ":" << a[k] << a[l] << '\n';
                return;
              }
        }
  cout << "00:00" << endl;
}

C. K-beautiful Strings

待补题

D. GCD of an Array

待补题

附录

这里放上用到的文件头和main函数(有更新,更了一个非常抽象的CV(a),用于无处理一键读入元素)

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
namespace Xiaoxia{
    #include<iostream>
    #include<vector>
    #include<cmath>
    #include<string>
    #include<algorithm>
    //不要用#define,使用using可以用ll格式转换,但是#define不行
    #define et '\n'
    #define reg register
    #define il inline
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define rrep(i,a,b) for(int i=(a);i>=(b);i--)
    #define cin(a) ll a;cin>>a
    #define dcin(a) ld a;cin>>a
    #define scin(a) string a;cin>>a
    #define CA cout<<ans<<et
    #define CY cout<<"YES"<<et
    #define CN cout<<"NO"<<et
    #define max(a,b) ((a>b)?(a):(b))
    #define min(a,b) ((a<b)?(a):(b))
    #define CV(x) for(auto &i:x)cin>>i
    //#define PP(l,r,CK) *ranges::partition_point(ranges::iota_view((l),(r)+1),(CK))
    string ANS[2] = { "No\n","Yes\n" };
    int M = 1e9 + 7;
    inline ll MO(ll x){return (x%M+M)%M;}
}
using namespace Xiaoxia;

void solve(){

}

int main() {
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    //pre();
    cin(t); while (t--)
    solve();
    return 0;
}