这次的题目挺简单的(指签到题
A
最小的数肯定去不掉,而不是最小的数一定可以在一定的操作后去掉,所以答案为 (n-最小数个数)
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '
'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
inline void read(int &x) {
int s=0;x=1;
char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
x*=s;
}
int buc[1005];
int main(){
int T; cin>>T;
while(T--){
set0(buc);
int n;
cin>>n;
rep(i,1,n){
int x;
cin>>x;
buc[x]++;
}
int res;
rep(i,1,100){
if(buc[i]){
res=n-buc[i];
break;
}
}
cout<<res<<endl;
}
return 0;
}
B
策略:负数和 (0) 肯定要选,如果说存在正数,那么看看最小的正数是否满足,如果满足就让答案 (+1)
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '
'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
inline void read(int &x) {
int s=0;x=1;
char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
x*=s;
}
const int N=1e5+5;
int a[N];
int main(){
int T; cin>>T;
while(T--){
int n; cin>>n;
rep(i,1,n) cin>>a[i];
sort(a+1, a+1+n);
int minv=INF;
int res=1;
rep(i,2,n){
minv=min(minv, a[i]-a[i-1]);
if(a[i]<=0) {
res++;
continue;
}
if(minv>=a[i]){
res++;
break;
}
}
cout<<res<<endl;
}
return 0;
}
C
简单的树形dp
一个重要结论:每个点取最小或最大值即可得到最优解。
f[u][0]
表示 (u) 点取最小值时候,(u) 点及其子树最大的贡献。
f[u][1]
表示 (u) 点取最大值时候,(u) 点及其子树最大的贡献。
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '
'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
#define int long long
inline void read(int &x) {
int s=0;x=1;
char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
x*=s;
}
const int N=1e5+5;
struct node{
int to, next;
}e[N<<1];
int h[N], tot;
void add(int u, int v){
e[tot].to=v, e[tot].next=h[u], h[u]=tot++;
}
// int minv[N], maxv[N];
int l[N], r[N];
int f[N][2];
int n, m;
void dfs(int u, int fa){
int resl=0, resr=0;
for(int i=h[u]; ~i; i=e[i].next){
int go=e[i].to;
if(go==fa) continue;
dfs(go, u);
resl+=max(f[go][0]+abs(l[u]-l[go]), f[go][1]+abs(l[u]-r[go]));
resr+=max(f[go][0]+abs(r[u]-l[go]), f[go][1]+abs(r[u]-r[go]));
}
f[u][0]=resl;
f[u][1]=resr;
}
signed main(){
int T; cin>>T;
while(T--){
tot=0, memset(h, -1, sizeof h);
read(n);
rep(i,1,n) read(l[i]), read(r[i]);
m=n-1;
while(m--){
int u, v; read(u), read(v);
add(u, v), add(v, u);
}
dfs(1, -1);
cout<<max(f[1][0], f[1][1])<<endl;
}
return 0;
}
D
将问题分成两个部分:
- 出现覆盖的情况
- 未出现覆盖的情况(也就是各个颜色占据的距离都是相等的)
考虑 (f[i]) 的状态转移方程。
对第一个部分:很容易想到这一部分的贡献:(sum_{j=1}^{i-1}f[j])
而对于第二个部分,因为都是等距的,所以这部分的贡献为 (d[i]) ,其中 (d[i]) 为 (i) 的约数数量。
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '
'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
inline void read(int &x) {
int s=0;x=1;
char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
x*=s;
}
const int N=2e6+6, mod=998244353;
ll f[N], s[N], d[N];
void get(int n)
{
for(int i=1; i*i<=n; i++)
for(int j=i;j<n/i;j++){
if(i==j) d[i*j]++;
else d[i*j]+=2;
}
}
int main(){
int n; cin>>n;
f[1]=1;
s[1]=1;
get(2*n); // 预处理出公约数 i 个数 d[i]
rep(i, 2, n) f[i]=(d[i]+s[i-1])%mod, s[i]=(s[i-1]+f[i])%mod;
cout<<f[n]<<endl;
return 0;
}