题目A 相邻相同字母删除
首先本题将所给字符串进行遍历,找到前后相同的两项,用这两项的n+2项进行替换,后面依次替换,最后两项置空(NULL)。但在替换过程中,需要注意,该项是否存在“后两项”。这就需要下面代码中关于后方项数的讨论。在替换结束后,因为i会自增1,所以还需考虑是否存在如“yuuy”这种消除后衍生出新的消除项的情况,因此需要i--,返回再次确认。
#include<stdio.h>
#include<string.h>
int main()
{
char arr[100000]={ 0 };
scanf("%s",&arr);
int len = strlen(arr);
for(int i=0;arr[i+1]!=NULL;i++)
{
lable:
if(arr[i]==arr[i+1])
{
if(arr[i+2]!=NULL&&arr[i+3]==NULL)//后面还剩一个
{
arr[i]=arr[i+2];
arr[i+1]=NULL;
arr[i+2]=NULL;
i--;
continue;
}
if(arr[i+1]!=NULL&&arr[i+2]==NULL)//后面没有了
{
arr[i]=NULL;
arr[i+1]=NULL;
break;
}
else//全都挪两位
{
for(int j=i+2;j<=len-1;j++)
{
arr[j-2]=arr[j];
}
arr[len-1]=NULL;
arr[len-2]=NULL;
i--;
goto lable;
}
}
}
printf("%s",arr);
return 0;
}
题目B 字符串相减
首先本题关于多样例的书写方法较新,能够认识即可。在遍历两个字符串数组过程中,遇到相同元素即将A串中对应元素置空。最后打印A串时,设置if条件,不打印NULL元素即可。
#include<stdio.h>
#include<string.h>
int main()
{
char s1[10000];
char s2[10000];
while(gets(s1)!=NULL&&gets(s2)!=NULL)
{
int len1 = strlen(s1);
int len2 = strlen(s2);
for(int i=0;i<len1;i++)
{
for(int j=0;j<len2;j++)
{
if(s1[i]==s2[j])
{
s1[i]=NULL;
}
}
}
for (int i1 = 0; i1 < len1; i1++)
{
if(s1[i1]!=NULL)
{
printf("%c",s1[i1]);
}
}
printf("\n");
}
}
题目G 上下火车
本题目考察了对于关键特征数字的敏感度,在枚举前7站的上下车人数后,总结出每站剩余人数。是关于w和t的式子。将w和t的系数单独取出,经分析发现符合特殊的斐波那契数列(前者需减1,后者需加1)。至于该思路的来源,可以由题目中的 “上车的人数都是前两站上车人数之和” 得出。然后因为t不是一个已知量,所以我们用已知的m去推导未知的t。m是最后一站的下车人数,也就是第(n-1)站的剩余人数,(n-1)站的wt系数利用两个数组可以轻松求出。
#include<stdio.h>
int main()
{
int w,n,m,x,t;
scanf("%d %d %d %d",&w,&n,&m,&x);
long int c1[100];//每站剩余人数w系数
long int c2[100];//每站剩余人数t系数
c1[0]=1;c1[1]=1;c1[2]=2;
for(int i=3;i<n-1;i++)
{
c1[i]=(c1[i-1]-1)+(c1[i-2]-1)+1;
}
c2[0]=0;c2[1]=0;c2[2]=0;c2[3]=1;
for(int j=3;j<n-1;j++)
{
c2[j]=(c2[j-1]+1)+(c2[j-2]+1)-1;
}
t = (m - c1[n-2]*w)/c2[n-2] ;
int happy;
happy = c1[x-1]*w + c2[x-1]*t;
printf("%d\n",happy);
return 0;
}
题目H 字符串反码
本题难度不大,依次讨论输入字符的类型即可,类型用它的ASCII码值确定。
#include<stdio.h>
#include<string.h>
int main()
{
char arr[80];
while(scanf("%s",&arr)!=EOF)
{
int len = strlen(arr);
char brr[len];
for(int i=0;i<len;i++)
{
if(arr[i]>='A'&&arr[i]<='Z')
{
brr[i]='Z'-arr[i]+'A';
}
else if(arr[i]>='a'&&arr[i]<='z')
{
brr[i]='z'-arr[i]+'a';
}
else
{
brr[i]=arr[i];
}
}
brr[len]='\0';
printf("%s\n",brr);
}
return 0;
}
题目I 回文素数
本题首先定义了两个函数,分别用于检验是否为素数和回文数。因输入数字有范围,所以我在检验回文数时采取了枚举的方式,可以有效实现降重。后续只需要遍历输入数组的元素即可,难度不大。
#include<stdio.h>
int test1(int x1)//素数返回1,否则返回0
{
if(x1==1)
{return 0;}
if(x1==2)
{return 1;}
if(x1>=3)
{
for(int k=2;k<x1;k++)
{
if(x1%k==0)
{return 0;break;}
if(k==x1-1)
{return 1;break;}
}
}
}
int test2(int x2)//回文返回1,否则返回0
{
int a,b,c,d;
if(x2>999)
{a=x2/1000;}
if(x2>99)
{b=(x2/100)%10;}
while(b>=10)
{
b=b-10;
}
if(x2>9)
{c=(x2/10)%10;}
while(c>=10)
{
c=c-10;
}
d=x2%10;
if(x2==1000)
{return 0;}
if(x2>99&&x2<=999)
{
if(b==d)
{return 1;}
else{return 0;}
}
if(x2>9&&x2<=99)
{
if(c==d)
{return 1;}
else
{return 0;}
}
if(x2<=9)
{return 1;}
}
int main()
{
int L,R;
while(scanf("%d %d",&L,&R)!=EOF)
{
int count=0;
int arr[R-L+1];
for(int i=L,j=0;i<=R;i++,j++)
{
arr[j]=i;//arr为需要的所有数字
}
for(int w=0;w<R-L+1;w++)
{
if(test1(arr[w])==1)
{
if(test2(arr[w])==1)
{
count++;
}
}
}
printf("%d\n",count);
}
return 0;
}
题目J 素数的间隔
本题定义了三个函数:检验输入值是否为素数、非素数的话分别找上下素数。返回值作差打印即可。在函数的构造过程中,涉及到了简单的递归思想,即函数的嵌套,用Test函数检验后两个函数+1后的值是否为素数。
#include<stdio.h>
int Test(int x1)//判断是否为素数,是返回1,不是返回0
{
if(x1==1)
{
return 0;
}
if(x1==2||x1==3)
{
return 1;
}
if(x1>3){
for(int i1=2;i1<=x1/2;i1++)
{
if(x1%i1==0)
{return 0;break;}
}}
return 1;
}
int cal_up(int x2)//向上找素数并返回该素数
{
for(int i2=1;i2<=1299709;i2++)
{
if(Test(x2+i2)==1)
{return x2+i2;break;}
}
}
int cal_down(int x3)//向下找素数并返回该素数
{
for(int i3=1;i3<=1299709;i3++)
{
if(Test(x3-i3)==1)
{return x3-i3;break;}
}
}
int main()
{
int n;
scanf("%d",&n);
if(Test(n)==1)
{
printf("0");
}
if(Test(n)==0)
{
int num = cal_up(n) - cal_down(n);
printf("%d",num);
}
return 0;
}
题目K 真假硬币
本题主要考察了对“均分”的理解、对于时间复杂度的认识,前者属于简单的数论相关内容、后者属于对算法的优化。在拿到题目时,我首先选择了采用枚举的方法寻找规律,相比于题目中极力诱导的“二分”,枚举后我发现“三分”的效果更优,同时也与题目下方的提示相合。
#include<stdio.h>
#include<math.h>
int Test(long x)
{
if(x==1)
{
return 0;
}
if(x>=2&&x<=3)
{
return 1;
}
if(x>=4&&x<=9)
{
return 2;
}
if(x>=10)
{
for(int i=1;i<=32;i++)
{
if(x>pow(3,i)&&x<=pow(3,i+1))
{
return i+1;
}
}
}
}
int main()
{
long n;
while(scanf("%ld",&n)!=EOF)
{
if(n==0)
{
break;
}
else
{
printf("%d\n",Test(n));
}
}
return 0;
}
题目L 大整数排序
对于字符串类型的长整数,首先需要比较的就是它的位数,位数多者大。对于相同位数的数字,再使用strcmp函数去比较其字典序。
提醒:对于多个样例的结构体,定义时可以为其设置数组(结构体数组),方便操作。(数组:对大量数据进行处理时减少计算量的一种方式。)
#include<stdio.h>
#include<string.h>
struct //存了数字和长度
{
char arr[1001];
int len;
}brr[201];
int main()
{
int n;
int len;
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;i++)//填充arr
{
scanf("%s",&brr[i].arr);
int lo = strlen(brr[i].arr);
brr[i].len = lo;
}
for(int j=0;j<n;j++)//排序
{
for(int k=j+1;k<n;k++)
{
if(brr[j].len<brr[k].len)//位数不同
{
brr[200]=brr[k];
brr[k]=brr[j];
brr[j]=brr[200];
}
if(brr[j].len==brr[k].len)//位数相同
{
if(strcmp(brr[j].arr,brr[k].arr)<0)
{
brr[200]=brr[k];
brr[k]=brr[j];
brr[j]=brr[200];
}
}
}
}
for(int t=n-1;t>=0;t--)//打印
{
printf("%s\n",brr[t].arr);
}
}
return 0;
}
题目M 日期排序
首先定义结构体,用于存放年月日。在比较大小时,应首先比较年,相同时比较月,再相同时比较日。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct date
{
int month;
int day;
int year;
} ;
int main()
{
int n;
scanf("%d",&n);
struct date p[n],t;
for(int i=0; i<n; i++)
{
scanf("%02d/%02d/%04d",&p[i].month,&p[i].day,&p[i].year);
}
for(int j=0; j<n-1; j++)
{
for(int i=0; i<n-1-j; i++)
{
if(p[i].year>p[i+1].year||p[i].year==p[i+1].year&&p[i].month>p[i+1].month||p[i].year==p[i+1].year&&p[i].month==p[i+1].month&&p[i].day>p[i+1].day)
{
t=p[i];
p[i]=p[i+1];
p[i+1]=t;
}
}
}
for(int i=0; i<n; i++)
{
printf("%02d/%02d/%04d\n",p[i].month,p[i].day,p[i].year);
}
}
部分题目(C、D、E、F)还不会写,就不放出来了,大家觉得有用的话,就点个赞吧。感谢你的支持,Jason会继续写下去的。对于C语言的学习,大家切忌直接搬运,还是要先看看思路再提交捏,Jason关键思路写的好详细的呢。