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;
}