38.3°C躺着敲oj(emo)

题目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关键思路写的好详细的呢。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值