A.数学:https://codeforces.com/contest/1992/problem/A
手搓样例,发现每次加1都是加当前最小的一个。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int t,a,b,c;
int cc[5];
int main(){
cin>>t;
while(t--){
cin>>cc[1]>>cc[2]>>cc[3];
for(int i=1;i<=5;i++){
sort(cc+1,cc+3+1);
cc[1]++;
}
cout<<cc[1]*cc[2]*cc[3]<<endl;
}
}
B.贪心:https://codeforces.com/contest/1992/problem/B
AC代码:
#include<bits/stdc++.h>
using namespace std;
int t,n,k,a[200010];
int main(){
cin>>t;
while(t--){
cin>>n>>k;
for(int i=1;i<=k;i++) cin>>a[i];
int h=-1;
int maxx=0;
for(int i=1;i<=k;i++){
maxx=max(maxx,a[i]);
if(a[i]==maxx) h=i;
}
int cnt=0;
for(int i=1;i<=k;i++){
if(i!=h) cnt+=a[i]-1;
}
cout<<n-maxx+cnt<<endl;
}
}
C.贪心:https://codeforces.com/contest/1992/problem/C
AC代码:
#include<bits/stdc++.h>
using namespace std;
int t,a[200010],n,m,k;
int main(){
cin>>t;
while(t--){
cin>>n>>m>>k;
int cnt=0;
for(int i=n;i>=k;i--){
a[++cnt]=i;
}
for(int i=k-1;i>m;i--) a[++cnt]=i;
for(int i=1;i<=m;i++) a[++cnt]=i;
for(int i=1;i<=n;i++) cout<<a[i]<<" ";
cout<<endl;
}
}
D.模拟:https://codeforces.com/contest/1992/problem/D
AC代码:
#include<bits/stdc++.h>
using namespace std;
int t,n,m,k;
char a[200010];
int main(){
cin>>t;
while(t--){
cin>>n>>m>>k;
char c;
for(int i=1;i<=n;i++){
cin>>c;
a[i]=c;
// cout<<a[i]<<" ";
}
int now=0;
while(k>=0&&now<=n){
if(now==0||a[now]=='L'){
//寻最远的木板
int find=0;
for(int i=now+m;i>=now+1;i--){
if(i>n){
now=n+1;
find=1;
}
else if(a[i]=='L'){
now=i;
find=1;
break;
}
}
if(find==0){
for(int i=now+m;i>=now+1;i--){
if(a[i]=='W'){
now=i;
find=1;
break;
}
}
}
if(find==0) k=-1;
// cout<<now<<" ";
}
else{
now++;
// if(now>n) k=100;
k--;
if(a[now]=='C'&&now<=n) k=-1;
}
}
if(k<0) cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
}
E.数学,枚举:https://codeforces.com/contest/1992/problem/E
直接枚举a,b显然行不通,我们不妨观察一下数字特征:
首先,不难看出最多不超过1e7的范围,我们不妨先从
枚举
,然后再枚举
的位数(也就是从
),这样我们就可以得到
的值了。
于是再枚举a(),这样b就可以直接得到,最后再检验一下即可。
整个复杂度约1e7,可以AC。
AC代码:
#include<bits/stdc++.h>
#include<string>
using namespace std;
int t,n;
int cnt[110];
vector<pair<int,int> > zu[110];
void init(){
for(int i=1;i<=100;i++){
string ck;
for(int k=1;k<=7;k++){
if(k==1) ck=to_string(i);
else ck+=ck;
}
for(int a=1;a<=10000;a++){
for(int k=1;k<=6;k++){
int ans=stoi(ck.substr(0,k));
int b=i*a-ans;
if(b<1||b>10000||b>i*a) continue;
if(i>=10){
if(2*a-b!=k) continue;
}
else{
if(a-b!=k) continue;
}
cnt[i]++;
zu[i].push_back({a,b});
}
}
}
}
int main(){
init();
cin>>t;
while(t--){
cin>>n;
cout<<cnt[n]<<endl;
for(int i=0;i<zu[n].size();i++){
cout<<zu[n][i].first<<" "<<zu[n][i].second<<endl;
}
}
}
F.数学:https://codeforces.com/contest/1992/problem/F
显然:能放就放,不能放就再开一个。
接着就是判断一个数是否可以放。一个朴素的想法是:
由于x不是很大,开一个cun数组,对于刚枚举到的数,就是看
是否有。
然后就是更新,我们把从的遍历一遍,按照刚才的方法更新即可。这样复杂度就是
我们发现,这样其实有点多余,真正会产生影响的是的因子。
也就是我们只要枚举x的因子即可,而一个数的因子一定,于是复杂度降成
这里有个细节:更新的时候要从大到小枚举,类似背包问题空间的优化,从小到大的化前面的会影响到后面的。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int meiju[100010];
int n,x,t,a[200010];
int cnt=0;
void init(){
for(int i=1;i<=x;i++){
if(x%i==0) meiju[++cnt]=i;
}
}
bool cun[200010];
int main(){
cin>>t;
while(t--){
cin>>n>>x;
memset(cun,0,sizeof(cun));
for(int i=1;i<=n;i++) cin>>a[i];
cnt=0;
init();
int ans=1;
cun[1]=1;
for(int i=1;i<=n;i++){
if(x%a[i]!=0||a[i]>x) continue;
if(cun[x/a[i]]){
memset(cun,0,sizeof(cun));
ans++;
cun[a[i]]=1;
cun[1]=1;
}
else{
for(int j=cnt;j>=1;j--){
if(meiju[j]<=a[i]||meiju[j]%a[i]!=0) continue;
cun[meiju[j]]=max(cun[meiju[j]],cun[meiju[j]/a[i]]);
}
cun[a[i]]=1;
}
}
cout<<ans<<endl;
}
}