11.2 22大数据c语言自测3题解

本文介绍了多个编程挑战,包括数组操作、一元多项式求导、蜘蛛纸牌游戏、稀疏矩阵判断、二维数组求和、代码抄袭检测和回文字符串识别。每个挑战都提供了详细的算法思路和C语言实现,旨在帮助读者提升编程和算法理解能力。
摘要由CSDN通过智能技术生成

在开头,先分享一篇看到的文章

原文链接:看完一个在校大学生的 Java 学习历程,我觉得我还能学得更多 - 力扣(LeetCode) 


1001 删除数组中的相同元素

描述

给定一个数组a,求删除相同元素(只保留1个)后剩下的元素个数。

输入

第一行为正整数n(n<=100)。

第二行有n个整数,表示数组的各个元素,数组元素已经按从小到大排序。

输出

输出一个整数,即删除相同元素后剩余的元素个数。

样例输入

3
1 1 2

样例输出

2

输入条件已经从小到大排序过了。在这里就是前后两两相互比较有没有一样的元素,如果说前后两个元素不一样。这里在定义fun函数的地方解释一下。把数组内第一个数固定住,然后逐个往后比较,前后对比如果值相同就不用管他,如果说遇到了一个元素和第一个不一样的话,把固定住的元素往后移动一位进行重新赋值。这里看代码了,相当于把数组a整个都重组了。

#include <stdio.h>
#define maxn 1001
int fun(int a[],int n){
  int i,j=1;
    for(i=1;i<n;i++){
      if(a[j-1]!=a[i])
		a[j++]=a[i];
	}
     return j;
}
 int main(){
 
	int a[maxn],i,n;
    scanf("%d",&n);
	   for(i=0;i<n;i++){
	    	scanf("%d",&a[i]);
	   }
	   n=fun(a,n);
	   
	     printf("%d",n);
 
	   
 return 0;
}

1002 一元多项式的导数

描述

设计函数求一元多项式的导数。(注:xn(n为整数)的一阶导数为n*xn-1。)

输入

以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。

输出

以与输入相同的格式输出导数多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。注意“零多项式”的指数和系数都是0,但是表示为“0 0”。

样例输入

3  4  -5  2  6  1  -2  0

样例输出

12  3  -10  1  6  0

简单题,基本的求导。

#include<stdio.h>
int main()
{
    int m,n,flag=1;
    while(scanf("%d %d",&m,&n)!=EOF){
        if(n>0){
            if(flag==1){
                printf("%d %d",m*n,n-1);
                flag=0;
            }else{
                printf(" %d %d",m*n,n-1);
            }
        }
    }
    if(flag==1)
         printf("0 0");
    return 0;
}

1003 蜘蛛纸牌

描述

Windows下有一款游戏叫“蜘蛛纸牌”,无聊的时候可以打发时间,由于仅仅打发时间,因此不想消耗脑细胞,CRQ准备玩最简单的“单色”模式,即全部都是“黑桃”的牌。游戏规则是对于点数相邻的两张牌,你可以将点数小的牌移动到点数大的上面,不断移动直到所有的牌都按先大后小的顺序叠成若干列就算过关。游戏菜单下还有一个功能是“显示可行的操作”用于提示当前是否还有可行的操作,由于CRQ仅仅打发时间,因此玩不下去时也经常执行该操作。现在的问题是:假设你是游戏的设计者,如何实现“显示可行的操作”这个功能?

为了简化问题,我们只判断最上面的那张牌还可不可以移动到别的牌上。

输入

输入数据有多组,每组10个整数,代表最上面那张牌的分值,每个整数取值是1~13,分别对应A、2、3、4、5、6、7、8、9、10、J、Q、K这些牌面分值。

输出

对于每组数据均输出一行,如果还有可行的操作,请输出YES,否则输出NO。

样例输入

2 4 2 5 6 4 7 13 6 2
1 1 1 1 1 1 1 1 3 5

样例输出

YES
NO
对于这道题的输入条件,其实也没有什么想到特别好的处理方法。最开始做的时候第一个想到的是在输入数组的时候直接用while(scanf("%d",&a[i])!=EOF)这种写法,但是在输入a数组时,已经在一个for循环之内了,这样写两个循环相互之间会冲突。但是题目又正好凑巧只有十个元素,那么就用了一种比较投机取巧的方法。在这里先把数组中的元素,也就是所有的牌从小到大排序,然后左右两两比较,看看有没有连接起来的可能。如果有可能就可以直接break了,我的习惯是进行到底,比较保险。

#include<stdio.h>
#include<string.h>
int main()
{
    void sort(int a[],int n);
    int a[10],i,j,k,d;
    
	while(scanf("%d%d%d%d%d%d%d%d%d%d",&a[0],&a[1],&a[2],&a[3],&a[4],&a[5],&a[6],&a[7],&a[8],&a[9])!=EOF){
    sort(a,10);
   
    for(i=0;i<10;i++)
    {
        if(a[i]+1==a[i+1])
        {
            printf("YES\n");
            break;

        }
        if(i==9)
        {
            printf("NO\n");
        }
    }
   

    }
    return 0;
    
}
void sort(int a[],int n)
{
    int i,j,t;
    for(i=1;i<n;i++)
    {
        for(j=0;j<n-1;j++)
        {
            if(a[j]>a[j+1])
            {
            t=a[j+1];
            a[j+1]=a[j];
            a[j]=t;
            }
        }
    }
}

1004 Contest Seating

描述

The participants start arriving, are taking seats at the computers. After practicing a bit, many of them leave temporarily in order to grab some snacks. Of course, this sometimes results in a new participant trying to use an already claimed computer. We want to figure out just how often this happens.

输入

The first line will contain the number K of input data sets. This is followed by the K data sets, each of the following format:
The first line contains two numbers P and M, the number of participants (1 <= P <= 500), and the number of machines (1 <= M <= 500). This is followed by P lines, each containing an integer between 1 and M, the number of the machine that
the participant is trying to sit down at first.

输出

For each data set, first output its number, then in a new line the total number of unsuccessful sitting attempts. An attempt is unsuccessful if by the time participant i is trying to sit at machine j, some other participant has already sat at machine j.

样例输入

3
4 1
1
1
1
1
4 4
1
2
3
4
4 4
1
4
1
4

样例输出

Data Set 1:
3
Data Set 2:
0
Data Set 3:
2


意思就是说,第一个出现的数字,是第一个人去占领的这台机器,后来再出现同样的数字,那么电脑被入侵的概率就加一。对于样例输入第二组的这种情况,4个人和四台不同的机器,每个人都有一台可以用,那么发生的概率就是0;第一组的这种情况,4个人和一台机器,那么第一个用上这个机器的人,被后面三个人入侵的概率就是3。数组遍历之后比较相同,如果说出现了一台机子几个人抢的情况,用b数组储存可能性,那么b数组对应的下标,就是在这台机子上发生被入侵的可能,这样子写表达的可能清楚一些。最后b数组遍历全体元素相加就是答案。

include<stdio.h>
#include<string.h>
#define maxn 1001
int main()
{
    int n,p,m,s=0,i,j,k,t,a[maxn],flag=0,b[maxn];
    memset(b,0,sizeof(b));
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d%d",&p,&m);
        for(j=0;j<p;j++)
        scanf("%d",&a[j]);
        for(k=1;k<=m;k++)
        {
            for(t=0;t<p;t++)
            if(a[t]==k)
            b[k]+=1;
        }
        for(t=1;t<=m;t++)
        if(b[t]>1)
        flag+=b[t]-1;
        

        printf("Data Set %d:\n",i);
        printf("%d\n",flag);
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        flag=0;


    }
    return 0;
}

1005 A-B problem

描述

A+B人见人爱,A-B也不甘落后,这个A-B求的是两个集合的差,就是做集合的减法运算。(当然,大家都知道集合的定义,就是同一个集合中不会有两个相同的元素,这里还是提醒大家一下)
呵呵,很简单吧?

输入

每组输入数据占1行,每行数据的开始是2个整数n(0<n<=100)和m(0<m<=100),分别表示集合A和集合B的元素个数,然后紧跟着n+m个元素,前面n个元素属于集合A,其余的属于集合B. 每个元素为不超出int范围的整数,元素之间有一个空格隔开.
如果n=0并且m=0表示输入的结束,不做处理。

输出

针对每组数据输出一行数据,表示A-B的结果,如果结果为空集合,则输出“NULL”,否则从小到大输出结果,为了简化问题,每个元素后面跟一个空格.

样例输入

3 3 1 2 3 1 4 7
3 7 2 5 8 2 3 4 5 6 7 8 
0 0

样例输出

2 3 
NULL

像这样同类型的题目还有一道,是A+Bproblem,那道题要求的是集合的并集。这道题要求的就是a中含有,而b中不含的元素。因为都是从小到大输入,a、b数组直接按照顺序遍历即可。在这里用p来判断是否重合,把不重合的元素(也就是a独有的元素存于c中)。排序后输出。

#include<stdio.h>
int  main()
{
int m,n,t;
while(scanf("%d%d",&m,&n)!=EOF){
        if(m==0&&n==0) break;
  int a[10000],b[10000],c[1000],i,j,l=0,hy=0;
for(i=0;i<m;i++)
 scanf("%d",&a[i]);
for(i=0;i<n;i++) 
scanf("%d",&b[i]);
for(i=0;i<m;i++)
    {
        int p=0;
        for(j=0;j<n;j++)
        if(a[i]==b[j])
         p=1;
        if(p==0) 
    {
    c[hy++]=a[i];
     l++;
    }         
    }
   for(i=0;i<l;i++)
    for(j=0;j<l-1-i;j++)
   if(c[j]>c[j+1]) 
   {
    t=c[j+1];
    c[j+1]=c[j];
    c[j]=t;
    }
for(i=0;i<l;i++) 
printf("%d ",c[i]);
if(l!=0) printf("\n");
if(l==0) printf("NULL\n");
}
}

1006  稀疏矩阵

描述

矩阵中非零元素的个数远远小于矩阵元素的总数,这一类矩阵我们往往称之为稀疏矩阵。对于稀疏矩阵,我们往往只需要记录非零元素即可,这样大大减少了数据的存储,起到压缩数据的作用。

给定一个N*M矩阵,判断它是否是稀疏矩阵。若为稀疏矩阵,输出非零元素的下标及其值,否则输出初始矩阵。

输入

输入数据的第一行有三个数n, m和d,n和m分别表示矩阵的行数和列数,d为一个小数。

接下来有n行,每行m个整数。

1<=n,m<=1000, 0<d<=0.5。

输出

若非零元素在总元素中的比例小于d,则该矩阵为稀疏矩阵,否则为稠密矩阵。

若为稀疏矩阵,先在第一行中输出n和m,再按照行优先的顺序下标从小到大输出非零元的行号(从0开始),列标(从0开始)和元素值,每行一个非零元。

若为稠密矩阵,则先在第一行中输出n和m,再输出原始矩阵。

任意两个数之间用空格隔开,行末没有多余空格。

样例输入

3 3 0.5
1 0 0
0 1 0
0 0 1

样例输出

3 3
0 0 1
1 1 1
2 2 1

这题题目描述出来的做法已经很明显了,用一个count来存非0元素的值,然后判断是不是稀疏矩阵。判断之后就是简单的输出。代码写的很明显了,不多说了。

#include<stdio.h>
#define MAXN 1001
int a[MAXN][MAXN];
int main()
{
	int n,m,i,j;
	double d,c;
	while(scanf("%d %d %lf",&n,&m,&d)!=EOF)
	{
		int count=0;
		for(i=0;i<n;i++)
		{
			for(j=0;j<m;j++)
			{
				scanf("%d",&a[i][j]);
			} 
		}
		for(i=0;i<n;i++)
		{
			for(j=0;j<m;j++)
			{
				if(a[i][j]!=0)
				{
					count=count+1;
					
				}
			}
		}
		c=count*1.0/(n*m);
		printf("%d %d\n",n,m);
		if(c>=d)
		{
			for(i=0;i<n;i++)
			{
				for(j=0;j<m-1;j++)
				{
					printf("%d ",a[i][j]);
				}
				printf("%d\n",a[i][m-1]);
			}
		}else
		{
			for(i=0;i<n;i++)
			{
				for(j=0;j<m;j++)
				{
					if(a[i][j]!=0)
					{
						printf("%d %d %d\n",i,j,a[i][j]);
					}
				}
			}
		}	
	}
	return 0;
}

1007 二维数组

描述

给定一个n行m列的二维数组,以及某个整数x,问二维数组中是否至少存在一行或一列,其元素之和恰好为x。

输入

输入数据的第一行为n,m,x(1<=n, m<=50)。
接下来有n行,每行有m个整数。

输出

如果二维数组中至少存在一行或一列,其元素之和为x,则输出YES,否则输出NO

样例输入

3 4 10
1 2 3 4
2 3 4 5
3 4 5 6

样例输出

YES

不算难题,第一个循环先行后列,第二个循环先列后行,注意细节。

#include<stdio.h>
#include<string.h>
#define maxn 1001
int main()
{
    int a[maxn][maxn],n,m,x,i,j,k=0,z=0,s[maxn],b[maxn];
    memset(s,0,sizeof(s));
    scanf("%d%d%d",&n,&m,&x);
    for(i=0;i<n;i++)
    {
        for(j=0;j<m;j++)
       scanf("%d",&a[i][j]);
    }
    for(i=0;i<n;i++){
for(j=0;j<m;j++)
s[i]+=a[i][j];
    }
    for(j=0;j<m;j++)
    {
        for(i=0;i<n;i++)
        b[j]+=a[i][j];
    }
    for(i=0;i<n;i++){
    if(s[i]==x)
    k+=1;
    }
    for(i=0;i<m;i++)
    {
        if(b[i]==x)
    z+=1;
    }
    if(k!=0||z!=0)
    printf("YES");
    else if(k==0&&z==0)
    printf("NO");
    return 0;



}

1008 代码抄袭

描述

考虑题目较难,同时为了鼓励同学们下去自己练习...我们今天把这题放上...
以前写过的,直接放代码就过了。要是做完又回去自己没做的同学,下次记得做不出的题回去尽量琢磨琢磨。
判断2个代码是抄袭是很必要的,但是,除了人来看,似乎没有什么好方法……
一个比较好的方法是比较编译后得二进制文件。
现在就来让你写个程序来比较两个二进制文件得差异度。
​​​​​​​

输入

第一行包含1个整数T,表示有T组数据。

每组数据包含两行。

第一行包含一个数字N1(<=1000)表示长度,一个空格符,一个长度为N1的由’0’和’1’字符构成得数组,表示第一个文件得信息。

第二行结构和第一行类似,长度为N2(<=1000)。

输出

判断两个1-0串的相似程度,如果长度都不同那么肯定不同,如果长度相同,统计相同位置的字符相同的个数,如果占到了整个长度得70%以上就说明有抄袭嫌疑,即

(相同字符个数)/(字符数组长度)>=0.700(精确到小数点后3位)。

样例输入

3
3 111
3 000
3 011
2 01
5 10010
5 10110

样例输出

No
No
Yes

这题的一个坑在于,要求相似度要在70%以上,计算相似度时要精确到小数点后三位。处理起来其实也方便。但是我第一次做的时候就把问题想复杂了,直接傻傻的除了个1000然后算完再乘回去,其实没必要这样,if语句判断的时候再数字后面加上三个0就可以了,前提是定义变量时,是要定义成浮点型。

#include<stdio.h>
main()
{
	int te,number;
	int temp1,temp2;
	int i,j;
	double result;
	double count;
	char a[1000],b[1000];
	scanf("%d",&number);
	for (te=1;te<=number;te++)
	{   count=0;
	    result=0;
		scanf("%d %s",&temp1,&a);
		getchar();
		scanf("%d %s",&temp2,&b);
		getchar();
		if(temp1!=temp2)
			printf("No\n");
		else
		{   
			for(i=0;i<temp1;i++)
			{
                    if(a[i]==b[i])
						count++;
			}
			result=count/temp1;
			if(result>=0.700)
				printf("Yes\n");
			else
				printf("No\n");
		}
		
		}
}

1009 (没找到名字)

描述

You may have heard of the book '2001 - A Space Odyssey' by Arthur C. Clarke, or the film of the same name by Stanley Kubrick. In it a spaceship is sent from Earth to Saturn. The crew is put into stasis for the long flight, only two men are awake, and the ship is controlled by the intelligent computer HAL. But during the flight HAL is acting more and more strangely, and even starts to kill the crew on board. We don't tell you how the story ends, in case you want to read the book for yourself :-)

After the movie was released and became very popular, there was some discussion as to what the name 'HAL' actually meant. Some thought that it might be an abbreviation for 'Heuristic ALgorithm'. But the most popular explanation is the following: if you replace every letter in the word HAL by its successor in the alphabet, you get ... IBM.

Perhaps there are even more acronyms related in this strange way! You are to write a program that may help to find this out.

输入

The input starts with the integer n on a line by itself - this is the number of strings to follow. The following n lines each contain one string of at most 50 upper-case letters.

输出

For each string in the input, first output the number of the string, as shown in the sample output. The print the string start is derived from the input string by replacing every time by the following letter in the alphabet, and replacing 'Z' by 'A'.

Print a blank line after each test case.

样例输入

2
HAL
SWERC

样例输出

String #1
IBM

String #2
TXFSD

其实是一道很简单的题目,直接用ascii码的加减即可完成。

#include<stdio.h>
#include<string.h>
#define maxn 51
int main()
{
    char str[maxn];
    int n,a,i,m=1;
    scanf("%d",&n);
    while(m<=n){
    scanf("%s",str);
    a=strlen(str);
    for(i=0;i<a;i++)
    {
        if(str[i]=='Z')
        str[i]='A';
    else
        str[i]+=1;
    }
    printf("String #%d\n",m);
    printf("%s",str);
    printf("\n\n");
    m++;
    }
    return 0;
}

1010 Palindromes

描述

Palindromes are strings that read the same both forwards and backwards. `Eye' is one such example (ignoring case). In this problem, you get to write a program to determine if a given word is a palindrome or not.

输入

Each line of input contains one word with no embedded spaces. Each word will have only alphabetic characters (either upper or lower case). 

输出

For each line of input, output either `yes' if the word is a palindrome or `no' otherwise. Don't print the quotes. Case should be ignored when checking the words. 

样例输入

eyE
laLAlal
Foof
foobar

样例输出

yes
yes
yes
no

思路很简单:把一个数输入到字符数组中,然后遍历,看看第一个和最后一个是否相等,第二个和倒数第二个是否相等,以此类推。

可以先定义一个函数,把字符数组里的元素全部都变成小写,或者全部变成大写也可以,转变过程可以看书,小写大写ascii码相差32,直接加减即可。

注:书上介绍了string.h里的一种函数叫strlwr,可以照着书上或者网上的教程学着用一下。但是直接调用库里自带的函数容易出现runtime error,而且还很难检查出原因。

#include<stdio.h>
#include<string.h>
#define maxn 1001
void zh(char str[])
{
    int n,i,j,k;
    n=strlen(str);
    for(i=0;i<n;i++)
    {
        if(str[i]>='A'&&str[i]<='Z')
        str[i]+=32;

    }


}
int main()
{
    int i,j,k,n,flag=0;
    char str[maxn];
    while(scanf("%s",str)!=EOF)
    {
        zh(str);
        n=strlen(str);
        for(i=0;i<(n+1)/2;i++)
        {
            if(str[i]!=str[n-1-i])
            {printf("no\n");
            flag=0;
            break;
            }
            else
            {
                flag+=1;

            }

            
        }
        if(flag!=0)
        printf("yes\n");
    }
    
return 0;
}

欢迎私信,评论区交流!



​​​​​​​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

captainfly_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值