#1615. 题面
题面
No testdata at current.
2024年语法周赛13题解
T1 变形虫
本题主要考查循环和条件判断的使用。
只要蛋糕的重量和变形虫当前的重量相同,变形虫重量变量变两倍即可。需要注意一下,重量有可能超出int范围
#include<bits/stdc++.h>
using namespace std;
int main(){
long long sum=0,a,n,ch[205];
cin>>a>>n;
for(int i=1;i<=n;i++){
cin>>ch[i];
if(a==ch[i])a*=2;
}
cout<<a;
return 0;
}
T2 海明码
从0开始一直递增枚举满足条件的数,判断这个数和之前的所有满足条件的数,是否两两之间满足条件。可以用异或符号直接算两个数不同位的结果,然后分解成二进制数统计有几个1即可。也可以两个数一起转二进制,在过程中统计不同位数。
参考代码 100分
#include<bits/stdc++.h>
using namespace std;
int n,d;
int a[70],lens,num;
int check(int x,int y)
{
int k=x^y,ans=0;
while(k>0)
{ if(k%2)
ans++;
k/=2;
}
return ans;
}
int main()
{
bool flag=1;
scanf("%d%d",&n,&d);
while(lens<n)
{
flag=1;
for(int i=1;i<=lens;++i)
if(check(a[i],num)<d) flag=0;
if(flag) a[lens++]=num;
num++;
}
for(int i=1;i<=n;++i)
{
printf("%d ",a[i-1]);
if((i%10)==0) cout<<endl;
}
return 0;
}
T3 自创除法
部分分做法:双重循环枚举数字的每一位,按位相除进行累加即可,注意数位为零时跳过累加即可
#include <iostream>
using namespace std;
int main()
{
long long a,b,a1,b1;
double sum=0;
cin>>a>>b;
a1=a,b1=b;
while(a1!=0)
{
if(a1%10==0){
a1/=10;
b1=b;
continue;
}
while(b1!=0)
{ if(b1%10==0){
b1/=10;
continue;
}
sum+=double(a1%10)/double(b1%10);
b1/=10;
}
a1/=10;
b1=b;
}
printf("%.2lf",sum);
return 0;
}
满分做法:把数字当成字符串处理,双重循环遍历数字的每一位。数字字符减去‘0’转数字,进行数位相除累加,依旧是要注意数位为零时,跳过不计算,否则会运行错误。
#include<bits/stdc++.h>
using namespace std;
char s1[1000000],s2[10000000];
double sum=0;
int main(){
sum=0;
scanf("%s%s",s1,s2);
for(int i=0;i<strlen(s1);i++){
if(s1[i]=='0')continue;
for(int j=0;j<strlen(s2);j++){
if(s2[j]=='0')continue;
sum+=double(s1[i]-'0')/double(s2[j]-'0');
}
}
printf("%.2lf\n",sum);
return 0;
}
T4 约瑟夫升级版
题意:每个人按照输入的顺序排成一圈,每个人都有他们独特的id。从1数到m,在1-m范围内报到 反序素数的出圈
部分分做法:模拟约瑟夫环,从1报数到m,报到反序素数就b数组标记为出圈。报数的人位置不停移动,到达队尾就从头再来。判断反序素数使用平常经常使用的判断素数和颠倒数字的方法,但是因为调用函数过多,会超时。
#include<bits/stdc++.h>
using namespace std;
int cnt,n,m,sum,shu=0,weizhi=1;
bool b[10000010];
long long a[10000000];
bool isprime(long long n){
if(n<2)return 0;
for(int i=2;i*i<=n;i++){
if(n%i==0)return 0;
}
return 1;
}
int reverse(int n){
int sum=0;
while(n){
sum=sum*10+n%10;
n/=10;
}
return sum;
}
int main(){
sum=0,shu=0,weizhi=1;
memset(b,0,sizeof(b));
cin>>n>>m;
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
while(sum<n){
if(b[weizhi]==0){
shu++;
if(isprime(shu)==1&&isprime(reverse(shu))==1){
sum++;
b[weizhi]=1;
cout<<a[weizhi]<<" ";
}
if(shu>=m)shu=0;
}
weizhi++;
if(weizhi>n)weizhi=1;
}
return 0;
}
满分做法:使用筛选法找素数,提前把素数的状态标记在isprme数组里,直接访问即可知道。
#include<bits/stdc++.h>
using namespace std;
int prime[10000000],cnt,n,m,sum,shu=0,weizhi=1;
bool isprime[100000000],b[10000010];
long long a[10000000];
void init(int n){
isprime[1]=1;
for(int i=2;i<=n;i++){
if(!isprime[i])prime[++cnt]=i;
for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
isprime[i*prime[j]]=1;
if(i%prime[j]==0)break;
}
}
}
int reverse(int n){
int sum=0;
while(n){
sum=sum*10+n%10;
n/=10;
}
return sum;
}
int main(){
sum=0,shu=0,weizhi=1;
memset(b,0,sizeof(b));
memset(isprime,0,sizeof(isprime));
cin>>n>>m;
init(10000000);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
while(sum<n){
if(b[weizhi]==0){
shu++;
if(isprime[shu]==0&&isprime[reverse(shu)]==0){
sum++;
b[weizhi]=1;
cout<<a[weizhi]<<" ";
}
if(shu>=m)shu=0;
}
weizhi++;
if(weizhi>n)weizhi=1;
}
return 0;
}