青岛市程序设计竞赛冲刺⑥(2023第四届上海市青少年算法竞赛小学组试题)
2.幸运数
原题:


原代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e7+5;
ll a[505]={0,6,8,66,68,86,88,666,668,686,688,866,868,886,888,6666,6668,6686,6688,6866,6868,6886,6888,8666,8668,8686,8688,8866,8868,8886,8888,66666,66668,66686,66688,66866,66868,66886,66888,68666,68668,68686,68688,68866,68868,68886,68888,86666,86668,86686,86688,86866,86868,86886,86888,88666,88668,88686,88688,88866,88868,88886,88888};
ll n,p=2;
string s[N],s1[N];
int main(){
// freopen("T2.in","r",stdin);
// freopen("T2.out","w",stdout);
cin>>n;
if(n<=62)cout<<a[n];
else{
s1[1]="6";
s1[2]="8";
while(n-p>0){
n-=p;
p*=2;
}
for(ll i=4;i<=p;i*=2){
for(ll j=1;j<=i/2;j++)s[j]=(string)("6"+s1[j]);
for(ll j=i/2+1;j<=i;j++)s[j]=(string)("8"+s1[j-i/2]);
for(ll j=1;j<=i;j++)s1[j]=s[j];
}
cout<<s1[n];
}
return 0;
}
AC代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll a[67],x=2,n,len;
string ans;
int main(){
// freopen("T2.in","r",stdin);
// freopen("T2.out","w",stdout);
cin>>n;
a[1]=1;
for(int i=2;i<=60;i++)x*=2,a[i]=x-1;
for(int i=1;i<60;i++){
if(n>=a[i]&&n<a[i+1]){
len=i;
n-=a[i];
break;
}
}
while(n>0){
ans=char(n%2+48)+ans;
n/=2;
}
int t=len-ans.length();
for(int i=1;i<=t;i++)ans="0"+ans;
for(int i=0;i<ans.length();i++){
if(ans[i]=='0')cout<<6;
else cout<<8;
}
return 0;
}
错误原因:
正解的规律是将幸运数字转换成二进制,而错解是运用组数的方法进行求解,所找的规律不同
3.连环画
原题:


原代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6+5,M = 3*N;
ll a[M],cnt[M];
int n,ans=0,Ok=0,t=1,n1;
bool p[M];
int main(){
// freopen("T3.in","r",stdin);
// freopen("T3.out","w",stdout);
cin>>n;n1=n;
for(int i=1;i<=n;i++)cin>>a[i],cnt[a[i]]++;
while(t<=n1){
Ok++;if(!p[a[t]])ans++;
p[a[t]]=1;
if(Ok>=2){
int p=-1;
for(int i=1;i<=3*n;i++){
if(cnt[i]==0){
p=i;
break;
}
}
if(p!=-1){
a[++n1]=p;
Ok-=2;
cnt[p]++;
}
}
t++;
}
cout<<ans;
return 0;
}
AC代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e6+5;
int n,a[2*N],ans,sum;
int main(){
cin>>n;
for(int i=1,x;i<=n;i++)cin>>x,a[x]++;
for(int i=1;i<=2*n;i++)if(a[i]>1)sum+=a[i]-1,a[i]=1;
int j=2*n;
for(int i=1;i<=2*n;i++){
if(a[i]){
ans=i;
sum++;
}else{
if(sum>1){
sum--;
ans=i;
}else{
for(int k=j;k>i;k--){
if(a[k]){
sum++;
a[k]=0;
j=k;
if(sum==2)break;
}
}
if(sum==2){
ans=i;
sum=1;
}else{
cout<<ans;
return 0;
}
}
}
}
return 0;
}
错误原因:
考虑情况不周全,且条件不分明
4.团队竞赛
原题:


原代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6+520;
pair<int,int>PI[N];
int n,X,a[N],k;
int main(){
// freopen("T4.in","r",stdin);
// freopen("T4.out","w",stdout);
cin>>n>>X;
for(int i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+n+1);
for(int i=1;i<=n;i++){
for(int j=i+1;a[j]-a[i]<=X&&j<=n;j++){
PI[++k].first=i;
PI[k].second=j;
}
}
cout<<ceil(k/3.0);
return 0;
}
AC代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int n,x,a[100005],last;
long long ans,m,s;
bool v[100005];
int main(){
cin>>n>>x;
for(int i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+n+1);
for(int i=1;i<=n;i++){
int p=upper_bound(a,a+n+1,a[i]+x)-a;;
if(v[p])continue;
v[p]=1;
if(last!=0)m=last-i;
m=m*(m-1)*(m-2)/6;
s=p-i;
s=s*(s-1)*(s-2)/6;
ans+=s-m;
last=p;
}
cout<<ans;
return 0;
}
错误原因:
根本性错误,没有想到区间和二分,思路不明确
5.集训题单
原题:


原代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e3+5,MOD = 998244353;
ll n,m,k,X,a[N],sum=0,sum1=0;
ll add(ll a,ll b){return ((a%MOD)+(b%MOD))%MOD;}
int main(){
// freopen("T5.in","r",stdin);
// freopen("T5.out","w",stdout);
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
cin>>k>>X;
for(int i=1;i<=n;i++)if(a[i]>=X)sum++;
for(int i=k;i<=m;i++)sum1=add(sum1,(m-i?(n-sum)*(sum-i+1):(sum-i+1)));
cout<<sum1%MOD;
return 0;
}
AC代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e3+5,MOD = 998244353;
ll n,m,k,X,a[N],sum=0,sum1=0,c[N][N],ans=0;
ll add(ll a,ll b){return ((a%MOD)+(b%MOD))%MOD;}
int main(){
// freopen("T5.in","r",stdin);
// freopen("T5.out","w",stdout);
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
cin>>k>>X;
for(int i=1;i<=n;i++){
if(a[i]>=X)sum++;
else sum1++;
}
for(int i=0;i<=n;i++)c[i][0]=c[i][i]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<i;j++){
c[i][j]=add(c[i-1][j-1],c[i-1][j]);
}
}
for(int i=k;i<=sum;i++){
if(i<=m){
if(i==m)ans=add(ans,c[sum][i]);
else ans=add(ans,c[sum][i]*c[sum1][m-i]);
}
}
cout<<ans;
return 0;
}
错误原因:
思路错误,正解运用杨辉三角求得组合数,统计两种情况后,运用乘法原理求解,而错解是累计个数的选法

浙公网安备 33010602011771号