【CodeForces训练记录】Codeforces Round 1016 (Div. 3)
训练情况

赛后反思
经典操作之枚举因数判质数不特判 \(1\),怒吃两发罚时
A题
直接瞪眼看样例,直接猜奇偶分类讨论,一分钟秒了
点击查看代码
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'
using namespace std;
void solve(){
int x; cin>>x;
if(x&1) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T; cin>>T; while(T--)
solve();
return 0;
}
B题
这题显然剩下只有一个数是最优的,因为 \(\frac{x}{x} = 1\),但是不能剩下零,所以我们考虑先删非零的数,留下一个非零的数,接下来就是考虑零的问题,如果零在那个数的右边也不行,所以需要把右边的零也删了,所以答案是非零个数-1+后导零的数量
点击查看代码
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'
using namespace std;
void solve(){
string s; cin>>s;
int cnt = 0;
for(int i = 0;i<s.size();i++) if(s[i] != '0') cnt++;
int add = 0,pos = s.size() - 1;
for(int i = s.size() - 1;~i;i--){
if(s[i] != '0'){
pos = i;
break;
}
}
add = s.size() - pos - 1;
// cout<<add<<endl;
cout<<cnt-1+add<<endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T; cin>>T; while(T--)
solve();
return 0;
}
C题
字符串拼接我们可以等效成 \(\times 10^{p}\),比如 22 3,就是 \(22 + 22 \times 10^{2} + 22 \times 10^{4}\),质数显然是除了 \(1\) 和自身没有其他因数,我们先不考虑 \(x=1\) 的情况,对于 \(k>1\) 时上述式子一定能提出来一个公因数 \(x(x \neq 1)\),所以一定不是质数,\(k=1\) 直接判断那个数是否是质数即可,复杂度是 \(O(logV)\) 的,接下来我们特殊考虑 \(x=1\) 的情况,由于七个一值域很小,按照题目描述拼接判断质数即可
点击查看代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
void solve(){
int x,k; cin>>x>>k;
bool flag = true;
if(x == 1){
int ck = 0;
for(int i = 1;i<=k;i++) ck = ck*10 + 1;
if(ck==1) flag = false;
for(int i = 2;i<=sqrt(ck);i++){
if(ck%i==0){
flag = false;
break;
}
}
if(flag) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
return;
}
for(int i = 2;i<=sqrt(x);i++){
if(x%i==0){
flag = false;
break;
}
}
if(!flag) cout<<"NO"<<endl;
else if(k>1) cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T; cin>>T; while(T--)
solve();
return 0;
}
E题
触发关键词最小值最大,直接考虑二分答案,我们二分 \(\operatorname{mex}\),对于 \(\operatorname{mex} = x\) 情况,我们可以推出来需要分成几段,和题目给出的 \(k\) 比较就是二分单调性了,求区间数我们可以遍历数组,如果当前所选的区间 \(\operatorname{mex}\) 满足了就去找下一个区间,维护不同数出现的个数和某个数是否出现过即可
点击查看代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N = 2e5 + 3;
int n,k;
int a[N];
bool pd(int x){
int cnt = 0;
int ans = 0;
vector<bool> v(N,0);
for(int i = 1;i<=n;i++){
if(a[i] < x && !v[a[i]]) v[a[i]] = 1,cnt++;
// cout<<i<<" "<<cnt<<endl;
if(cnt == x) v.assign(N,0),cnt=0,ans++;
}
// cout<<k<<" "<<x<<" "<<ans<<endl;
return ans >= k;
}
;
void solve(){
cin>>n>>k;
for(int i = 1;i<=n;i++) cin>>a[i];
int l = 0,r = 1e9 + 1,m;
while(l<r){
m = l + r + 1 >> 1;
if(pd(m)) l = m;
else r = m-1;
}
cout<<l<<endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T; cin>>T; while(T--)
solve();
return 0;
}

浙公网安备 33010602011771号