【C/PTA】数组进阶练习(三)

本文结合PTA专项练习带领读者掌握数组,刷题为主注释为辅,在代码中理解思路,其它不做过多叙述。

7-1 数组-排名查询

已知N个人的成绩排名,按排名从小到大输出这N个人的编号。
输入格式:

第一行输入一个正整数N(N<=100);

第二行输入N个互不相同的整数,每个整数均取值为1到N。
输出格式:

输出仅一行,包括N个整数,其中第i个整数表示排第i名的人的编号。

数字之间用一个空格隔开,最后一个数字之后没有空格。
输入样例:

5
2 3 1 5 4

输出样例:

3 1 2 5 4

#include <stdio.h>
int main()
{
	int n;scanf("%d",&n);
	int a[n];
	
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}//输入23154
	
	
	int count=0;
	for(int i=1;i<=n;++i) //假设第一次循环i=1
	{
		for(int j=0;j<n;++j)
		{
			if(a[j]==i)   //j=2时a[j]=1 
			{
				if(count==n-1) //对最后一个数字进行处理
				{
					printf("%d",j+1);
				}
				else 
				printf("%d ",j+1); //输出编号3
				count++;
				break;
			}
		}
	}
	
}

7-2 数组-人数过半

输入N个数,求出现次数超过总数一半的数。数据保证存在这个数。
输入格式:

第一行输入一个正整数N(N<1000);

第二行输入N个数,每个数的绝对值不超过1e9。
输出格式:

输出一个数,即出现次数超过总数一半的数。
输入样例:

5
2 3 2 2 4

输出样例:

2

#include <stdio.h>
int main()
{
	long long int n;scanf("%lld",&n);long long int a[n];
	for(long long int i=0;i<n;i++)
	{
		scanf("%lld",&a[i]);	
	}
	
	for(long long int i=0;i<n-1;i++)
	{
		for(long long int j=0;j<n-i-1;j++)
		{
		if(a[j]>a[j+1])
		{
			long long int t=a[j+1];
			a[j+1]=a[j];
			a[j]=t;
		    }	
		}
	}
	
	//进行最大数的判断
	long long int count=1;
	for(long long int i=0;i<n-1;i++)
	{
		if(a[i]==a[i+1])
		count++;
		else
		count=1;
		
		if(count>n/2)
		{
		printf("%lld",a[i]);
		break;
		}	
	}
}

7-3 数组-数值插入

输入一个非降序列和一个数,将这个数插入到非降序列中并保持序列非降。
输入格式:
第一行输入一个正整数N(N<100000);
第二行按顺序输入N个非降的整数,保证每个整数在int范围;
第三行输入一个待插入的整数(int范围)。

输出格式:
输出仅一行,包括N+1个整数,为插入给定的数后的非降序列,数字之间用一个空格隔开,最后一个数字之后没有空格。

输入样例:
5
3 5 7 10 15
8

输出样例:
3 5 7 8 10 15

//将一个数插入到非降序列中并保持序列非降
#include <stdio.h>
int main()
{
	int n;scanf("%d",&n);int a[n+1];
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
	
	int x;
	scanf("%d",&x);
	
	for(int i=0;i<n;i++)
	{
	//x最小的情况
	if(x<=a[0])
	{//逆序往后移
		for(int j=n-1;j>=0;j--)
		{
			a[j+1]=a[j];
		}
		//x赋值给a[0]
		a[0]=x;
		break;
	}
	
	//x在其中的情况
	else if(x>=a[i]&&x<=a[i+1])
	 {
		//逆序往后移
		for(int j=n-1;j>=i+1;j--)
		{
			a[j+1]=a[j];
		}
		//把x赋值给a[i+1]
		a[i+1]=x;
		break;
	 } 
	 
	 
	 //x最大的情况
	 else if(x>=a[n-1])
	 {
	 	a[n]=x;
	 }

	}
	
	for(int i=0;i<=n;i++)
	{
		if(i==n)
		printf("%d",a[i]);
		else
		printf("%d ",a[i]);
	}
}

7-4 数组-冒泡排序

给定n个整数,请用冒泡排序法对这n个整数从小到大排序。
输入格式:

第一行输入一个正整数N(N<=1000);

第二行输入N个整数(int范围)。
输出格式:

输出仅一行,为排完序后的N个数,两个数之间用一个空格隔开。
输入样例:

5
3 5 4 3 5

输出样例:

3 3 4 5 5

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

	for(int i=0;i<n;i++)
	{
		if(i==n-1)
		printf("%d",a[i]);
		else
		printf("%d ",a[i]);
	}
}

7-5 数组-删除元素

输入一个序列和一个数,将这个序列中与该个数相等的元素删除,保持其他元素先后顺序不变。
输入格式:

第一行输入n(2<n<=100);

第二行输入n个正整数(小于1e9);

第三行输入一个正整数k,为要删除的元素值。
输出格式:

输出仅一行,即进行删除后的序列,两个元素之间有一个空格作为分隔符,末尾无空格。
输入样例:

4
3 5 3 2
3

输出样例:

5 2

方法一:特殊值法

#include <stdio.h>
int main()
{
	int n;scanf("%d",&n);int a[n];
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
	
	int x;
	scanf("%d",&x);
	
	for(int i=0;i<n;i++)
	{
		if(x==a[i])
		{
			a[i]=1999999;//取特殊值
		}
	}
	
	
	
	for(int i=0;i<n;i++)
	{
		if(a[i]!=1999999)
		{
			if(i==n-1||a[i+1]==1999999)
			printf("%d",a[i]);
		    else
			printf("%d ",a[i]);
		}
	
   }
}

方法二:使用双指针来实现。一个指针用于遍历原数组,另一个指针用于记录删除指定元素后的新数组的位置。

#include <stdio.h>
int main(){
    int n;scanf("%d",&n);int a[n];
    
	for(int i=0;i<n;i++) 
	{
        scanf("%d",&a[i]);
    }

    int x;
    scanf("%d",&x);

    int k=0;//用于记录新数组

    for(int i=0;i<n;i++) 
	{
        if(a[i]!=x) 
		{
            a[k]=a[i];//将非指定元素移到前面
            k++;
        }
    }

    for (int i=0;i<k;i++) 
	{
		if(i==k-1)
		printf("%d",a[i]);
        else
		printf("%d ", a[i]);
    }
}

7-6 数组-歌手得分

青年歌手大奖赛中,评委会给参赛选手打分。选手得分规则为:去掉一个最高分和一个最低分,然后计算出平均分即为选手最终得分。
输入格式:

第一行输入一个正整数n(2<n<=100),表示评委的人数;

第二行输入n个整数,表示n个评委的打分。
输出格式:

输出仅一行,即选手的最终得分,结果保留2位小数。
输入样例:

4
100 99 98 97

输出样例:

98.50

#include <stdio.h>//使用冒泡排序即可
int main()
{
	int n;scanf("%d",&n);int a[n];double sum;
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}


	for(int i=0;i<n-1;i++)
	{
		for(int j=0;j<n-i-1;j++)
		{
			if(a[j]>a[j+1])
			{
				int t=a[j];
				a[j]=a[j+1];
				a[j+1]=t;
			}
		}
	}
	
	for(int i=1;i<=n-2;i++)
	{
		sum+=a[i];
	}
	double aver=sum/(n-2);
	printf("%.2f",aver);
}

7-7 数组-前K个成绩

已知N个人的成绩,编号从1到N,输出成绩排名前K个人的成绩。
输入格式:

第一行输入一个正整数N(N<=100);

第二行输入N个正整数(范围为1到100),即学生的成绩;

第三行输入一个正整数K(K>=1)。
输出格式:

输出仅一行,即前K个人的成绩。成绩从高到低输出。每两个数据之间有一个空格,末尾没有空格。
输入样例:

5
10 20 30 40 50
2

输出样例:

50 40

#include <stdio.h>//冒泡排序即可
int main()
{
	int n;scanf("%d",&n);int a[n];
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
	int k;scanf("%d",&k);


	for(int i=0;i<n-1;i++)
	{
		for(int j=0;j<n-i-1;j++)
		{
			if(a[j]<a[j+1])
			{
				int t=a[j];
				a[j]=a[j+1];
				a[j+1]=t;
			}
		}
	}
	
	for(int i=0;i<k;i++)
	{
		if(i==k-1)
			printf("%d",a[i]);
		else
		printf("%d ",a[i]);
	}
}

7-8 数组-绝对值排序

输入n(n<=100)个整数,按照绝对值从大到小排序后输出。绝对值相同的两个数,原始值较小的那个数靠前。
输入格式:

第一行输入一个整数n(1<=n<=100);

第二行输入n个待排序的整数(int 范围)。
输出格式:

输出排序后的结果,两个数之间用一个空格隔开,末尾没有空格。
输入样例:

3
3 -4 2

输出样例:

-4 3 2

#include <stdio.h>
int main()
{
	int n;scanf("%d",&n);int a[n],b[n];
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
		b[i]=a[i];//用数组b来跟踪数组a的状态
		if(a[i]<0)
		{
			a[i]*=-1;
		}
		
	}


	for(int i=0;i<n-1;i++)
	{
		for(int j=0;j<n-i-1;j++)
		{
			if(a[j]<a[j+1])
			{
				int t=a[j];
				a[j]=a[j+1];
				a[j+1]=t;  //冒泡排序
				
				int s=b[j];
				b[j]=b[j+1];
				b[j+1]=s;
			}
			
			if(a[j]==a[j+1])//处理绝对值相同的两个数
			{
				if(b[j]>b[j+1])
				{
					int q=b[j+1];
					b[j+1]=b[j];
					b[j]=q;
				}
			}
		}
	}
	
	for(int i=0;i<n;i++)
	{
		if(i==n-1)
		{
			if(b[i]<0)
			printf("%d",b[i]);
			else
			printf("%d",a[i]);
		}
			
		else
		{
			if(b[i]<0)
			printf("%d ",b[i]);
			else
			printf("%d ",a[i]);
		}
		
	}
}

7-9 数组-该死的数学课

为了提高菇菇们的基本素质来抵抗清明SAMA的恐怖袭击,麻麻决定给菇菇们上数学课(数学课有什么用啊喂!(#`O′) ?!)。麻麻给了菇菇们N个从2 开始的连续偶数,要求它们每M个整数计算出平均值,并输出。菇菇们太难过了,该死的数学课总是让人想哭,你能帮帮它们么?
输入格式:

输入仅一行,包括两个整数N(<=100)和M。
输出格式:

输出每M个连续偶数的平均值,末尾不足M个按实际个数计算输出。
输入样例:

3 2

输出样例:

3 6

#include <stdio.h>
int main()
{
	int n,m;scanf("%d%d",&n,&m);
	int a[n];a[0]=2;
	for(int i=1;i<n;i++)
	{
		a[i]=a[i-1]+2;
	}
	
	int groupcount=n/m;
	int remain=n%m;
	int sum,aver;
	int j=0,end=m,i;
	
	for(int k=1;k<=groupcount;k++)
	{//对每组进行处理
		sum=0;
		for(i=j;i<end;i++)
		{
			sum+=a[i];	
		}
		aver=sum/m;
		
		if(i==n)//对不存在余数时末尾空格的处理
		printf("%d",aver);
		else
		printf("%d ",aver);
		
		
		j+=m;
		end+=m;
	//每组处理完后 区间向右移m个单位
	}
	
	if(remain>0)
	{//处理剩余个数
		int all=0;
		for(int i=groupcount*m;i<n;i++)
		{
			all+=a[i];
		}
		int x=all/(n-groupcount*m);
		printf("%d",x);
	}

}

7-10 数组-麻麻的起司猫

广袤的戈壁上,为首的菇菇麻麻养了一群以节操为食的起司猫(都没节操喂菇菇了啊喂!还养猫?!)。麻麻每次考虑它们的DM值喂给它们节操。为了让起司猫们不要吃太饱,麻麻决定每次喂给DM值最低的起司猫ai块节操。吃下节操的起司猫DM值将相应地增加ai。

输入格式:
第一行输入两个正整数N,M(0<N<=100,M<=10),表示麻麻共有N只起司猫,进行M次喂食;
第二行包括N个整数,表示每只起司猫最初的DM值;
第三行包括M个整数,表示每次喂食的节操ai。

输出格式:
输出仅一行,表示M次喂食过后DM值最低的起司猫的DM值(保证数据不超过10^9)。

输入样例:
3 1
1 2 3
3

输出样例:
2

#include <stdio.h>
int main()
{
	int n,m;scanf("%d%d",&n,&m);int a[n],b[m];
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
	
	for(int i=0;i<m;i++)
	{
		scanf("%d",&b[i]);
	}
	
	
	for(int i=0;i<m;i++)
	{
		//次数作为外层循环
		int less=0;
		for(int j=1;j<n;j++)
		{
			if(a[j]<a[less])
			{
				less=j;   
			}

		}
		a[less]+=b[i];//喂食给最小的猫    
	}
	
	
    int min=a[0];
	for(int i=0;i<n;i++)
	{
		if(min>a[i])
		min=a[i];
	}
	printf("%d",min);
}

7-11 数组-小光头的反攻

小姑凉自从找到了一直拥有蓝爸爸的方法后就再也不需要小光头了,小光头觉得很难过。于是小光头偷偷跟着小姑凉一起去上数学课,想知道小姑凉怎么变得这么厉害(跟数学课真的有关系么?= =)。他发现从小就只会玩火的小姑凉数学真的糟透了,于是他想出了一个办法,他和小姑凉打赌,如果小姑凉不能解出他给的题目,小姑凉就要把蓝爸爸让给他,还不能生气,要跟他一起愉快地玩耍。小姑凉涉世未深,于是天真地答应了。

小光头的题目是这样的:小光头家有一楼梯共M级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法?

当然,从小就只玩火的小姑凉一定是解不出来的啦,你能帮帮她么?
输入格式:

第一行包含一个整数N,表示共有N组数据;

接下来有N行,每行包含一个整数M(1<=M<=40),表示楼梯的级数。
输出格式:

对于每组数据中的楼梯级数,输出不同走法的数量。
输入样例:

3
1
2
3

输出样例:

1
1
2

#include <stdio.h>
int main()
{
    int n;scanf("%d",&n);
	while(n--)
	{
		int m;scanf("%d",&m);
		int a[50];
		
		a[1]=1;//到达第一阶的走法为1
		a[2]=1;//...为2
		
		for(int i=3;i<=m;i++)
		{
			a[i]=a[i-1]+a[i-2];
		}
		printf("%d",a[m]);
	}
}

7-12 数组-无聊的游戏

Alice和Bob 整天都喜欢玩无聊的游戏,今天他们玩的游戏的规则是两人轮流从自己的 牌堆的最上方取一张牌,牌上有一个数字,谁的数字大谁就获胜,数字相同时两人都不 算获胜,问最后谁获胜的次数多。输出获胜次数多的人的名字及获胜的次数。获胜次 数相同时算Bob获胜。
输入格式:

第一行为一个正整数N(0 < N <= 1000),表示每个人有N张牌。

第二行包含N个数字,为Alice的牌的大小。

第三行包含N个数字,为Bob牌的大小。

(牌的大小为正整数且不超过1000,输入数字的顺序就是牌堆的牌从上到下的顺序)。
输出格式:

输出有两行,第一行为获胜者的名字;

第二行为获胜的次数。
输入样例1:

5
1 2 4 4 5
5 4 3 2 1

输出样例1:

Alice
3

输入样例2:

5
1 2 3 4 5
5 4 3 2 1

输出样例2:

Bob
2

#include <stdio.h>
int main()
{
	int n;scanf("%d",&n);
	int a[n],b[n];
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=0;i<n;i++)
	{
		scanf("%d",&b[i]);
	}
	
	
	int alice=0,bob=0;
	for(int i=0;i<n;i++)
	{
		if(a[i]>b[i])
		alice++;
		else if(a[i]<b[i])
		bob++;
	}
	
	if(alice>bob)
	printf("Alice\n%d",alice);
	else if(alice==bob)
	printf("Bob\n%d",bob);
	else
	printf("Bob\n%d",bob);
}

7-13 数组-Shc的数字

Shc 有一堆数字。这些数字十分的乱,有正有负。Shc 现在想从这些数字中挑选出一段连续的数字去送给他最喜欢的MAZE。Shc 知道MAZE 喜欢数字越大越好。所以他希望能够选出数字和最大的一段数字送给MAZE。现在需要你算出这段序列的和是多少。

输入格式:
第一行为一个正整数N(0 < N <= 100000),表示有N个数;
第二行输入N个数 Ai (-1000 <= Ai<= 1000)。

输出格式:
输出仅一个整数,表示最大的一段数字和值。

输入样例:
5
-1 2 -3 4 5

输出样例:
9

#include <stdio.h>
int main()
{
	int n;scanf("%d",&n);int x,nowall=0,max=-9999;//nowall表示当前序列和
	for(int i=0;i<n;i++)
	{
		scanf("%d",&x);
		if(x>nowall+x)
		{
			nowall=x;//如果x 大于 包含x的序列和,则说明nowall为负数
			//此时把序列更新
		}
		else
		nowall+=x;
		
		if(nowall>max)
		max=nowall;
	}
	
	printf("%d",max);
}
//拿2、-3、4、5举例
//一开始nowall为0,所以nowall加2,变为2,因为max为-9999,所以max变为2
//输入-3,同理,nowall变为-1,nowall不会大于max,所以max仍为2
//输入4,4+nowall大于nowall,所以nowall被更新为4,也就是说现在从4开始计算序列
//4大于max,所以max变为4
//输入5,所以nowall+5变成9,9大于max,所以序列和为9

7-14 数组-简单的斐波那契数列

斐波那契数列是一种非常有意思的数列,由0和1开始,之后的斐波那契系数就由之前的两数相加。用数学公式定义长度为n斐波那契数列F则可以看成如下形式:

F_0=0;

F_1=1;

F_i=F_{i-1}+F_{i-2}(2<=i<n)

由于斐波那契数列的增长速度很快,我们在斐波那契数列上进行取模操作,得到对应的长度为n的F’数列:

F_0’=0;

F_1’=1;

F_i’=(F_{i-1}’+F_{i-2}’)%1000000007(2<=i<n)

现在给你一个数列,你需要判断它是否为F’数列。

输入格式:
第一行包含一个正整数n(1<=n<=1000),表示有n个数;
第二行包含n个非负整数,均在int范围内。

输出格式:
输出仅一行,如果输入的数列是长度为n的F’数列则输出“YES”,否则输出“NO”。

输入样例1:
4
0 1 1 3

输出样例1:
NO

输入样例2:
8
0 1 1 2 3 5 8 13

输出样例2:
YES

#include <stdio.h>
int is(int n,int a[])
{
	if(n==1)
	{
		if(a[0]==0)
		return 1;//仅有0 则是F'数列
		else
		return 0;
	}
	
	
	int b1=0,b2=1,c;
	for(int i=2;i<n;i++)
	{
		c=(b1+b2)%1000000007;
		if(a[i]!=c)
		return 0;//如果有一个数不相等,则肯定不是F'数列
		b1=b2;
		b2=c;
	}//如果循环能正常结束,则是F'数列
	return 1;
}

int main()
{
	int n;scanf("%d",&n);int a[n];
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
	
	if(is(n,a))
	printf("YES");
	else
	printf("NO");
	
}

7-15 数组-简单的游戏

HHD学长很强,他玩VAN游戏总是赢。

这天他拿出N张牌,想和你玩个游戏,游戏的规则如下:
每张牌的点数为Ai(1<=i<=N),两人从牌堆顶轮流取牌,为了表示尊重,由学长先手取牌,最后点数之和大的获胜。

学长是个好面子的人,如果他输了,他会很不开心。你是个懂事的学弟,为了尽可能让学长赢,你可以趁学长不注意,在某一轮取牌结束后丢掉这张牌。如果丢掉这张牌后,学长还是要输,则输出“RUN”;否则输出你要丢掉的是第几轮取到的牌,使得学长的点数和尽可能大过你。
输入格式:

第一行输入一个正整数N(2 <= N <= 1000),表示有N张牌;

第二行输入N个整数,为牌的点数(牌的点数均为正整数且不超过1000,输入数字的顺序就是牌堆的牌从上到下的顺序)。
输出格式:

输出仅一行,输出一个整数,表示你要丢掉第几次取的牌才能让学长赢得漂亮;否则输出“RUN”。
输入样例1:

5
1 2 4 4 5

输出样例1:

2

输入样例2:

6
1 2 1 4 1 6

输出样例2:

RUN

#include <stdio.h>
int main()
{
	int n;scanf("%d",&n);int x;
	
	int maxmy=0;//你当前摸到的最大的牌
	int maxmycount=1;//你要丢牌的轮数
	int allmy=0;//你的点数和
	int allhe=0;//他的点数和
	
	
	
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&x);
		if(i%2==1)
		allhe+=x;//1 2 3
		else
		{
			if(x>maxmy)//如果你摸到的牌比你之前的都大
			{
				maxmy=x;
				maxmycount=i/2;
			}
			allmy+=x;
		}
	}
	
	if(allmy-maxmy<allhe)
	printf("%d",maxmycount);
	else
	printf("RUN");
		
}

7-16 数组-买买买

一次,HHD学长路过一个地摊,发现地摊上陈列着一排算法书,从1-N编号(1<=N<=1000000)。每本书价格为Ai(1<=Ai<=100)。于是他想考考你,当他给出一个区间[L,R],你要立即回答出这个区间内书的价格总和,如果你答对了,他就买下这些书。我们的HHD学长还真是富有啊!
输入格式:

第一行输入两个正整数N,Q(0 < N <= 1000000),N表示书的数量,Q表示询问的次数(0<Q<=10000);

第二行包括N个整数,表示N本书的价格;

接下来Q行,每行两个整数L、R,表示区间(1<=L<=R<=N)。
输出格式:

输出共Q行,每行对应一次询问的答案。
输入样例:

8 3
5 4 7 2 5 8 7 7
1 3
8 8
4 5

输出样例:

16
7
7

#include <stdio.h>
int main()
{
	int n,q;
	scanf("%d%d",&n,&q);int a[n];
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
	int l,r;
	for(int i=0;i<q;i++)
	{
		int sum=0;
		scanf("%d%d",&l,&r);
		for(int i=l-1;i<r;i++)
		{
			sum+=a[i];
		}
		printf("%d\n",sum);
	}
	
	
}

7-17 数组-牌面累加

粉红猪和呲溜喵在玩游戏,规则如下:每个人有N张牌,每张牌有一个数字,从第一张牌开始累加,累加和大的获胜。
输入格式:

第一行包含一个正整数N(0 < N <= 1000),表示有N张牌;

第二行包含N个整数,为呲溜喵的牌的大小;

第三行包含N个整数,为粉红猪牌的大小;

牌的大小可正可负,输入数字的顺序就是牌堆的牌从1到N的顺序。
输出格式:

输出仅一行,为获胜者的名字(pig或者cat);若平局则输出“sad”(不包含引号)。
输入样例1:

5
1 2 4 3 5
5 4 3 2 1

输出样例1:

sad

输入样例2:

5
1 2 3 4 5
5 -1 -1 -1 -1

输出样例2:

cat

#include <stdio.h>
int main()
{
	int n;scanf("%d",&n);int a[n];
	int sum=0,all=0;
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
		sum+=a[i];
	}
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
		all+=a[i];
	}
	if(all>sum)
	printf("pig");
	else if(all==sum)
	printf("sad");
	else
	printf("cat");
}

7-18 数组-咸鱼翻身

粉红猪比较无聊,他会每次改变当前所有咸鱼的状态(正面翻成反面,反面翻成正面),经过m次操作后,n条咸鱼中有几条是正面朝上的呢?
输入格式:

第一行输入两个正整数n,m(1<=n<=1000,0<=m<=1000)。n代表咸鱼数量,m代表操作次数。

第二行包含n个整数(0或1),表示咸鱼的初始状态,其中0代表反面,1代表正面。
输出格式:

输出仅一个整数,表示经过m次操作后,正面朝上的咸鱼数。
输入样例:

3 3
1 0 1

输出样例:

1

#include <stdio.h>
int main()
{
	int n,m;scanf("%d%d",&n,&m);int a[n];
	int count=0;
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
		if(a[i]==1)
		count++;
	}
	
	if(m%2==0)//经过偶数次操作就相等于什么都没做
	printf("%d",count);
	else
	printf("%d",n-count);
}

7-19 数组-冰欺凌球

呲溜喵很喜欢吃冰淇凌,特别喜欢夹冰淇凌球,现在给出呲溜喵已经加的冰淇凌球的半径,你能从大到小输出每颗冰淇凌球的体积吗?
输入格式:

第一行输入一个正整数N(0 < N <= 1000),表示有N个冰淇凌球;

接下来N行每行输入一个半径r(r 为1到100的任意实数)。
输出格式:

输出共N行,每行一个数字,表示一个冰淇凌的体积(体积保留两位小数,且按照从大到小的顺序)。

Pi = acos(-1.0)
输入样例:

3
1.2
2.4
3.1

输出样例:

124.79
57.91
7.24

#include <stdio.h>
#include <math.h>
int main()
{
	int n;scanf("%d",&n);double a[n];
	for(int i=0;i<n;i++)
	{
		scanf("%lf",&a[i]);
		a[i]=acos(-1.0)*4/3*a[i]*a[i]*a[i];
	}


//冒泡排序
	for(int i=0;i<n-1;i++)
	{
		for(int j=0;j<n-i-1;j++)
		{
			if(a[j]<a[j+1])
			{
				double t=a[j];
				a[j]=a[j+1];
				a[j+1]=t;
			}
		}
	}
	
	for(int i=0;i<n;i++)
	{
		printf("%.2f\n",a[i]);
	}

}

7-20 数组-粉红猪的斐波那契数列

粉红猪很喜欢斐波那契数列,现在希望你给出第n项的结果。
输入格式:

输入仅一行,包含一个正整数n(1<=n<=55)。
输出格式:

输出仅一个整数,表示斐波那契数列第n项的值。
输入样例:

3

输出样例:

2

#include <stdio.h>
int main()
{
	int n;
	scanf("%d",&n);
	
	long long int a=1,b=1;
	if(n==1)
	printf("%lld",a);
	else if(n==2)
	printf("%lld",b);
	else
	{
     	long long int c;
	    for(int i=3;i<=n;i++)
    	{
		c=a+b;
		a=b;
		b=c;
    	}
    	printf("%lld",c);
	}

}

7-21 序列元素删除

粉红猪不喜欢一些数字,所以他不希望这些数字出现在序列中。现在请你来帮粉红猪删除这些数字。
输入格式:

输入一共四行。

第一行输入一个正整数N(1<=N<=1000);

接下来一行包括N个整数;

第三行一个正整数M(0<=M<=100),代表粉红猪不喜欢的数的个数;

接下来一行包括M个数,代表粉红猪不喜欢的数(保证互不相同)。
输出格式:

输出处理后的序列,其他元素位置不变(行末无空格,仅有回车);如果删除后没有元素存在,只输出行末的回车。
输入样例:

6
1 2 5 3 4 5
1
5

输出样例:

1 2 5 3 4

#include <stdio.h>

struct number
{
	int value;
	int isabandoned;//是否需要删除
};

int main()
{
	int n;scanf("%d",&n);
	struct number a[n];
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i].value);
		a[i].isabandoned=0;//初始化 不需要删除
	}
	
	
	int m;scanf("%d",&m);int b;
	for(int i=0;i<m;i++)
	{
		scanf("%d",&b);
		
		for(int j=n-1;j>=0;j--)
		{//从后往前遍历 找到第一个匹配的数字并将其标记为需要删除
		//如 1 2 3 1序列,当b=1时,从后往前遍历,最后的1被标记,然后退出循环
			if(a[j].value==b)
			{
				a[j].isabandoned=1;
				break;
			}
		}
	}
	
	int hasprinted=0;
	for(int i=0;i<n;i++)
	{
		if(a[i].isabandoned==0)//不需要删除
		{
			if(hasprinted==0)//如果是第一个未被删除的数字,则直接输出
			{
				printf("%d",a[i].value);
				hasprinted=1;
			}
			else
			{//如果是后面的未被删除的数字,则先输出一个空格再输出数字
				printf(" %d",a[i].value);
			}
			
//不能使用传统的“仅当i为n-1时输出%d 其余时候输出空格+%d”来实现,因为最后一个数可能会被删除



		}
	}
	printf("\n");
}

7-22 数组-田地之争

转眼间双十一又来了,又到了戈壁上菇菇一族分配土地的日子(什么奇葩设定啊!)。为了公平起见,麻麻想出了一个聪明的办法:将土地分为N块,菇菇们一起到每块土地区域接受任务,最后完成任务最多的菇菇有优先选择权。因为可能在一个区域上重复接受任务,菇菇们记混了任务属于哪个区域,你能帮忙它们抢到选择权么?
输入格式:

第一行输入一个整数N(<=100),表示共有N个区域。

接下来有多行,每行两个整数a和b,表示在a区域接受了b个任务(同一个区域可能接受多次),当a、b同为0时结束输入。
输出格式:

输出共N行,每行包含两个整数a和b,a为区域编号,b表示a区域共接受了多少任务。(要求按区域编号从小到大排序,区域编号不大于100)
输入样例:

3
1 3
2 3
3 4
1 7
0 0

输出样例:

1 10
2 3
3 4

#include <stdio.h>
int main()
{
	int n;scanf("%d",&n);
	int task[100]={0};

    int a,b;
	while(1)
	{
		scanf("%d%d",&a,&b);
		if(a==0&&b==0)
		break;
		task[a-1]+=b;
	}
	
	for(int i=0;i<n;i++)
	{
		printf("%d %d\n",i+1,task[i]);
	}
}

7-24 数组-令人发指的清明SAMA

你猜的没错,是在广袤的草泥马戈壁上,还是那个名为清明SAMA的丧心病狂的逗比,因为她调戏菇菇的逗比行为遭到了菇菇们的反抗,并对她实施了一次打击报复,于是清明SAMA决定趁菇菇们不注意报复那些曾经企图反抗的菇菇们。

她发明了一种炸弹,能烧死一个方向上所有的节操,于是她深夜潜入菇菇们种植节操的地方企图烧死尽可能多的节操。可是清明SAMA还是一个非常有职业道德的逗比,她坚持烧死最多的曾经反抗她的菇菇们的节操。
输入格式:

第一行包括两个个正整数N,M(0<N<=100,M<=100),表示一片N*M的节操种植地。

接下来N行,每行M个数,若数字为1表示节操种植在该位置的菇菇曾经企图反抗清明SAMA,0则表示没有。
输出格式:

输出仅一行,包括两个整数。

第一个整数是0或1,其中0表示行,1表示列;

第二个数表示第几行或第几列(编号从1开始),代表清明SAMA在该行或该列投掷炸弹能烧死最多的曾经反抗她的菇菇们的节操。如果有多个结果优先输出行且序号最小的。
输入样例:

3 3
1 1 1
0 1 0
0 0 0

输出样例:

0 1

#include <stdio.h>
int main()
{
	int n,m;scanf("%d%d",&n,&m);int a[n][m];
	for(int i=0;i<n;i++)
	for(int j=0;j<m;j++)
	scanf("%d",&a[i][j]);
	int c[n];
	for(int i=0;i<n;i++)
	{
		c[i]=0;
		//c[i]储存每一行的和
		for(int j=0;j<m;j++)
		{
			c[i]+=a[i][j];
		}
	}
	
	
	int d[m];
	for(int i=0;i<m;i++)
	{
		d[i]=0;
	}
	for(int i=0;i<m;i++)
	{//d[i]储存每一列的和
		for(int j=0;j<n;j++)
		{
			d[i]+=a[j][i];
		}
	}
	
	//找到数组的最大值
	int max1=c[0],count1=1;int maxss[n];maxss[0]=0;
		for(int i=0;i<n;i++)
		{
			if(max1<c[i])
			{
				max1=c[i];
				count1=1;
				maxss[0]=i;
			}
			else if(max1==c[i])
			{
				maxss[count1]=i;
				count1++;
			}
		}
		
		
	int max2=d[0],count2=1;int maxxx[m];maxxx[0]=0;
		for(int i=0;i<m;i++)
		{
			if(max2<d[i])
			{
				max2=d[i];
				count2=1;
				maxxx[0]=i;
			}
			else if(max2==d[i])
			{
				maxxx[count2]=i;
				count2++;
			}
		}
	
	if(max1>=max2)//优先输出行
	printf("0 %d",maxss[0]+1);
	else
	printf("1 %d",maxxx[0]+1);
}

7-23 数组-菇菇叛徒

残忍的清明SAMA为了报复社会决定残害菇菇一族,于是她派遣了一些被她黑化的菇菇到菇菇家族里去当卧底。但是菇菇一族还是有聪明的菇菇发现了,于是报告了麻麻,麻麻决定召集所有菇菇,找出卧底。
输入格式:

第一行包括两个正整数N,M(0<N,M<=100),表示所有的菇菇站成了N*M的矩阵。

接下来N行,每行M个数表示每个菇菇的状态。如果菇菇状态为0则表示菇菇为健康善良的菇菇,如果菇菇状态为1则表示菇菇为被清明SAMA黑化的菇菇。
输出格式:

第一行输出一个整数ans,表示叛徒菇菇的个数。

接下来ans行,每行两个整数,表示叛徒菇菇所在的行列值(行列编号从1开始)。
输入样例:

2 3
0 0 1
0 1 0

输出样例:

2
1 3
2 2

#include <stdio.h>
int main()
{
	int n,m;scanf("%d%d",&n,&m);int a[n][m];
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			scanf("%d",&a[i][j]);
		}
	}
	
	
	int count=0;
	int b[n*m][2];
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				if(a[i][j]==1)
				{
					//表示叛徒所在的行列值
					b[count][0]=i+1;
					b[count][1]=j+1;
					
					count++;
										
										
				}
			}
		}
		
	printf("%d\n",count);
	for(int i=0;i<count;i++)
	{
		printf("%d %d\n",b[i][0],b[i][1]);
	}
		
}

7-25 数组-麻麻的难题

从前,在一片戈壁上居住着一群菇菇家族。菇菇麻麻管理着所有菇菇的饮食。但是因为环境实在太恶劣了,菇菇麻麻已经找不到足够的节操(菇菇一族的食物,不要问我为什么)来喂养所有的菇菇。为了让菇菇一族继续繁衍下去,麻麻秉着优胜劣汰的原则,决定放逐DB值最低的那些菇菇,让他们自生自灭。
输入格式:

第一行包括两个正整数N,M(0<N,M<=100),表示所有的菇菇站成了N*M的矩阵;

接下来N行,每行M个整数(<100007),表示每个菇菇的DB值。
输出格式:

第一行输出一个整数ans值,表示共有几个菇菇的DB值为最低的。

接下来ans行,每行两个数表示该菇菇所在的行列值。(行列编号从1开始)。
输入样例:

2 3
1 4 -3
7 -3 0

输出样例:

2
1 3
2 2

#include <stdio.h>
int main()
{
	int n,m;scanf("%d%d",&n,&m);int a[n][m];
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			scanf("%d",&a[i][j]);
		}
	}
	
	
	int count=0,min=a[0][0];
	int b[n*m][2];//用于记录行列值
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			if(min>a[i][j])
			{//如果找到更小的,则重置矩阵b
				min=a[i][j];
				b[0][0]=i+1;
				b[0][1]=j+1;
				count=1;		
			}
			else if(min==a[i][j])
			{
				b[count][0]=i+1;
				b[count][1]=j+1;
				count++;						
			}
		}
	}
		
	printf("%d\n",count);
	for(int i=0;i<count;i++)
	{
		printf("%d %d\n",b[i][0],b[i][1]);
	}
		
}

7-26 数组-残忍的麻麻

又是在广袤的草泥马戈壁上,在经过第一次的放逐后不久,日渐减少的节操量让菇菇麻麻不得不再次考虑放逐菇菇家族的部分菇菇(实在太残忍了…>_<…必须烧死!)因为经过第一次的放逐,留下的菇菇们DB值都差不多,于是菇菇麻麻决定把DM(不要问我这是什么奇葩值!)值也加入考虑因素。

麻麻将根据情况考虑DB值与DM值的比例a,b(a+b=1)。每个菇菇的最终值为a* DB值+b* DM值。值最低的菇菇将被放逐。
输入格式:

第一行包括一个正整数N(0<N<=1000),表示共有N个菇菇;

接下来一行包括两个浮点数a,b,分别表示DB值与DM值的比列;

接下来N行,每行两个整数,表示每个菇菇的DB值和DM值(DB,DM<1e9)。
输出格式:

第一行输出一个ans值,表示共有几个菇菇的DB值为最低的;

接下来一行有ans个数,表示哪些菇菇的值是最低的,编号之间用空格隔开,行末无空格(编号从1开始)。
输入样例:

3
0.5 0.5
1 2
2 2
2 1

输出样例:

2
1 3

 #include <stdio.h>
int main()
{
	int n;scanf("%d",&n);
	double a,b;scanf("%lf%lf",&a,&b);double c[n][2],e[n];
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<2;j++)
		{
			scanf("%lf",&c[i][j]);
		}
	}
	

	for(int i=0;i<n;i++)
	{
		e[i]=c[i][0]*a+c[i][1]*b;
	}

	

    double min=e[0];int f[n][1],count=0;
    for(int i=0;i<n;i++)
    {
		if(min>e[i])
		{
			min=e[i];
			f[0][0]=i+1;
			count=1;
		}
		else if(min==e[i])
		{
			f[count][0]=i+1;
			count++;
		}
	}
	
	printf("%d\n",count);
	for(int i=0;i<count;i++)
	{
		printf("%d",f[i][0]);
		if(i!=count-1)
		printf(" ");
	}
	
}

7-28 数组-初至宿舍

由于堵车,阿翔到宿舍楼下时,天色渐晚。阿翔本来就瘦弱,加上一路上与学长们激战,已筋疲力尽。他将自己的行李放倒在路旁,坐在上面歇歇脚。45度仰望,阿翔看到了有些宿舍的灯光已然亮起。毕竟是无聊的阿翔,反正也没什么事情可以做,于是他就想到了下面这个问题——

如果把有N * M间宿舍的一栋楼看成一个N * M的矩阵,假设一开始所有宿舍的灯都是关着的,现分别给行和列编号(行:1,2,…,N;列:1,2,…,M),并给出K个操作,操作的类型可能有如下两种:

1.(R , X),表示将行的编号为 X的整数倍 的所有灯都变为其相反的状态。

2.(C , Y),表示将列的编号为 Y的整数倍 的所有灯都变为其相反的状态。

(相反的状态,即将原本亮着的灯变为暗的,将原本暗着的灯变为亮的。)

经过K个操作后,还剩多少间宿舍的灯是亮着的?
输入格式:

第一行为三个整数N (0 < N <= 100)、M (0 < M <= 100)、K (0 <= K <= 100);

接下来有K行,每行第一个数据为一个字符,可能是R或C。紧接着是一个空格,空格后是一个正整数,且该正整数的值不会大于100。
输出格式:

输出仅一行,即最后亮着的灯的数目。
输入样例:

4 3 3
R 2
R 4
C 2

输出样例:

5

#include <stdio.h>
go(int a[101][101],char c,int b,int n,int m)
{
	if(c=='R')
	{
		for(int i=1;i<n+1;i++)
		{//遍历行
			if(i%b==0)//如果是整数倍
			{
				for(int j=1;j<m+1;j++)
				{//把该行中0置1、1置0
					if(a[i][j]==0)
						a[i][j]=1;
					else
					    a[i][j]=0;
				}
			}
		}
	}
	
	else if(c=='C')
	{
		for(int i=1;i<m+1;i++)
		{
			if(i%b==0)
			{
				for(int j=1;j<n+1;j++)
				{
					if(a[j][i]==0)
						a[j][i]=1;
					else
					    a[j][i]=0;
				}
			}
		}
	}
}


int main()
{
	int n,m,k;scanf("%d%d%d",&n,&m,&k);int a[101][101];
	for(int i=1;i<n+1;i++)
	{
		for(int j=1;j<m+1;j++)
		{
			a[i][j]=0;//初始化灯灭为0
		}
	}
	
	for(int i=0;i<k;i++)
	{
		int b;char c;
		scanf(" %c%d",&c,&b);
		go(a,c,b,n,m);
	}
	
	int count=0;
	for(int i=1;i<n+1;i++)
	{
		for(int j=1;j<m+1;j++)
		{
			if(a[i][j]==1)
			count++;
		}
	}
	printf("%d",count);
	
}

7-29 数组-宿舍的灯

不知道是在哪里,有着一个奇怪的学校,这个学校的宿舍的灯的开关可以控制这个宿舍所在的这一层,以及每层和当前宿舍同一个位置的宿舍的灯。现在这个学校有一个奇怪的人,他有着每间宿舍的钥匙,而且他还喜欢去按每间宿舍的灯的开关。现在按顺序给出他按了灯开关的宿舍号。问最多的时候有多少盏灯是亮着的。(假设一开始所有的灯都是关着的)
输入格式:

第一行为两个正整数N,M,其中N表示有N层楼,每层楼有N间房(1 <= N <= 9);
M表示这个奇怪的人共按了M次开关 (0 <= M <= 20)。

接下来M行,每行一个三位的整数,表示每次按下开关的宿舍编号。整数的最高位表示宿舍所在的楼层,中间一位是0,最低位表示宿舍在这层楼的第几间。
输出格式:

输出一个整数,表示最多的时候亮着的灯的数量。
输入样例:

3 3
201
102
103

输出样例:

6

//题目可简化为:有一个矩阵,初始化为0表示未开灯。
//如果触碰第一层第三列的开关,则第一层由0变1、全亮,第三列也全亮;
#include <stdio.h>
#include <math.h>
int main()
{
	int n,m;scanf("%d%d",&n,&m);int num,c[10][10]={0};int max=-1;
	if(m==0)
	{
	printf("0");return 0;	
	}
	for(int i=0;i<m;i++)
	{
		int sum=0;
		scanf("%d",&num);//输入
		int floor=num/100,room=num%10;
		
		//先使本房间变化
		c[floor][room]=pow(c[floor][room]-1,2);
		
		//再使每列或每行变化
        for(int i=1;i<=n;i++)
        c[floor][i]=pow(c[floor][i]-1,2);
        for(int i=1;i<=n;i++)
        c[i][room]=pow(c[i][room]-1,2);
        
        //又经过两次行列的变化之后,本房间相当于没变
        
        //计算个数
        for(int i=1;i<n+1;i++)
            for(int j=1;j<n+1;j++)
				sum+=c[i][j];

        
        
        if(max<sum)
        max=sum;
    }
    printf("%d",max);	
}

7-30 数组-矩阵交换

Shc 有一个N*M的数字矩阵。因为shc是个喜新厌旧的人,所以他每天都会交换这个矩阵中的两个同样大小的子矩阵。现在给出shc每天对矩阵的操作描述,问经过t天后这个数字矩阵会变成怎样?

输入格式:

第一行为两个正整数N,M(0 < N,M <= 1000);

接下来N行每行M个整数;

第N+2行输入一个整数t ( 1 <= t <= 10 );

接下来t行,每行输入5个整数(x1,y1,x2,y2,K),分别表示两个子矩阵的左上角的坐标,以及两个矩阵的大小。数据保证两个子矩阵不会重叠。

输出格式:

输出共N行M列,表示经过t次变换后的矩阵。

输入样例:

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

输出样例:

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

#include <stdio.h>
void fun(int a[1000][1000],int x1,int y1,int x2,int y2,int k)
{//此时x1、y1、x2、y2均已减一
	int t[1000][1000];
	for(int i=0;i<k;i++)
	{
		for(int j=0;j<k;j++)
		{
			t[i][j]=a[x1+i][y1+j];
		}
	}
//函数功能类似于:
//t=a;
//a=b;
//b=t;
    for(int i=0;i<k;i++) 
	{
        for(int j=0;j<k;j++)
		{
            a[x1+i][y1+j]=a[x2+i][y2+j];
        }
    }

    for(int i=0;i<k;i++) 
	{
        for(int j=0;j<k;j++) 
		{
            a[x2+i][y2+j]=t[i][j];
        }
    }
}



int main()
{
	int n,m;scanf("%d%d",&n,&m);
	int a[1000][1000];
	for(int i=0;i<n;i++)
	for(int j=0;j<m;j++)
	scanf("%d",&a[i][j]);
	int t;scanf("%d",&t);
	while(t--)
	{
		int x1,y1,x2,y2,k;scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&k);
		fun(a,x1-1,y1-1,x2-1,y2-1,k);
	}
	
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
			{
				if(j!=m-1)
				printf("%d ",a[i][j]);
				else
				printf("%d",a[i][j]);
			}
		printf("\n");
	}
	
}

7-31 数组-土豪shc

在一个N* N的矩形广场上总共有N*N个摊位。每个摊位上都有卖着各种各样的东西。因为shc是一个大土豪。所以他买东西都是把一排或者一列上的摊位上的东西全部买下来。

已知每个摊位上的商品价值是这个摊位的坐标和,即X+Y。Shc买完东西后这行或这列的所有摊位价值都变成0。

现在给出shc买东西的操作顺序。问每次购买花了多少钱。
输入格式:

第一行为两个正整数N,Q(0 < N,Q <= 10000),其中N表示矩形大小,Q表示购买的次数;

接下来Q行,每行有一个字母R和一个数字,字母值为R,表示行,字母值为C,表示列;数字则表示是哪一行或者哪一列。
输出格式:

输出为Q行,为每次购买所花费的金钱。
输入样例:

3 7
R 2
C 3
R 2
R 1
C 2
C 1
R 3

输出样例:

12
10
0
5
5
4
0

#include <stdio.h>
int main()
{
	int n,q;scanf("%d%d",&n,&q);
	getchar();
	int row[10001]={0};//用于记录每行是否被购买过,初始值为0
	int col[10001]={0};//用于记录每列是否被购买过
	for(int i=0;i<q;i++)
	{
		char x;scanf("%c",&x);getchar();
		int num;scanf("%d",&num);getchar();
		int sum=0;
		
		if(x=='R')
		{
			for(int j=1;j<=n;j++)
			{
				if(row[num]==0&&col[j]==0)
				{
					sum+=(j+num);
				}
			}
			row[num]=1;
		}
		else
		{
			for(int j=1;j<=n;j++)
			{
				if(row[j]==0&&col[num]==0)
				{
					sum+=(j+num);
				}
			}
			col[num]=1;
		}
		
		//如果都被购买过,直接输出sum为0即可
		//如果都没被购买过,累加即可
		printf("%d",sum);
		if(i!=q-1)
		printf("\n");
	}
}

7-32 数组-矩阵乘法

对于给定的一个M* N大小的矩阵A和一个N* M大小的矩阵B,请你帮忙计算一下矩阵A乘以矩阵B的结果。
输入格式:

第一行输入两个正整数M和N(3 <= N,M <= 20);

接下来是M行,每行N个整数,即矩阵A的元素;

再接下来是N行,每行M个整数,即矩阵B的元素。

每两个整数之间均以空格作为分隔符。
输出格式:

输出共M行,每行M个整数,即矩阵A和矩阵B相乘得到的新矩阵。

同一行两个整数之间用一个空格符隔开,每行末尾没有空格。

保证新矩阵中的最大值不会超过int范围。
输入样例:

3 2
1 1
2 2
1 1
2 2 2
1 1 1

输出样例:

3 3 3
6 6 6
3 3 3

#include <stdio.h>
int main()
{
	int m,n;scanf("%d%d",&m,&n);long long int a[m][n];
	for(int i=0;i<m;i++)
	{
		for(int j=0;j<n;j++)
		{
			scanf("%d",&a[i][j]);
		}
	}
	
	
	int b[n][m];
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			scanf("%d",&b[i][j]);
		}
	}
	
	
	int c[m][m];
		for(int i=0;i<m;i++)
		{
			for(int j=0;j<m;j++)
			{
				c[i][j]=0;
				for(int k=0;k<n;k++)
				{
					c[i][j]+=(a[i][k])*(b[k][j]);
				}
				
			}
		}
		
	
	for(int i=0;i<m;i++)
	{
		for(int j=0;j<m;j++)
		{
			printf("%d",c[i][j]);
			if(j!=m-1)
			printf(" ");
		}
		if(i!=m-1)
		printf("\n");
	}
}

7-33 数组-胖虎和大熊

数学老师把胖虎和大熊叫到办公室,因为胖虎和大熊数学考试又没有及格,老师很生气决定惩罚他们,如果胖虎和大熊能解决老师手头上的这个问题,就减轻对他们的惩罚。大熊知道自己做不出来,所以向你求助。

问题是这样的:有T个班级,每个班级有n个学生,问你每个班级有几名学生的数学分数低于平均分。
输入格式:

第一行包含一个正整数T(0 < T <= 50),即有T个班级;

接下来有2*T行,每两行的第一行有一个正整数n(n<60)代表学生数,第二行有n个整数,代表每个学生的数学分数,分数的取值范围为[0,100]。
输出格式:

输出共T行,每行一个整数,分别表示每个班级数学成绩小于平均分的人数(按照输入的班级顺序)。
输入样例:

2
5
27 45 63 85 99
4
80 80 80 80

输出样例:

3
0

#include <stdio.h>
int main()
{
	int t;scanf("%d",&t);
	for(int i=0;i<t;i++)
	{
		int n;scanf("%d",&n);
		int a[n],count=0;double sum=0,aver;
		for(int i=0;i<n;i++)
		{
		   scanf("%d",&a[i]);
		   sum+=a[i];
		}
		aver=sum/n;
		for(int i=0;i<n;i++)
		{
		   if(a[i]<aver)
		   count++;
		}	
	printf("%d\n",count);
	}

}

7-34 数组-转置矩阵

给定一个n*m的矩阵,请你帮忙求出这个矩阵的转置矩阵。
输入格式:

第一行包含两个正整数n,m(0 < n,m <= 1000)。

接下来有n行,每行包含m个正整数,每两个数之间用一个空格隔开。所有的正整数均满足小于等于1000。
输出格式:

输出共m行,每行有n个正整数,每两个数之间用一个空格隔开,行末没有空格。即原矩阵的转置矩阵。
输入样例:

3 2
1 2
3 4
4 5

输出样例:

1 3 4
2 4 5

#include <stdio.h>
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	int a[1000][1000];
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			scanf("%d",&a[i][j]);
		}
	}


	for(int j=0;j<m;j++)
	{
		for(int i=0;i<n;i++)
		{
			printf("%d",a[i][j]);
			if(i!=n-1)
			printf(" ");
		}
		printf("\n");
	}
	
}

7-35 数组-排队吹风

在Code镇里,实力代表一切,包括排队在天台吹风的时候,绝不允许能力值低的人排在能力值高的人前面先吹风。一天,HHD学长来到天台,准备根据队伍里所有人的能力值重新整顿队伍。HHD学长真的很强,他自己的能力值是∞,所以当他整理好队伍后,自己只要站到队伍的最前面就可以了。
输入格式:

第一行输入一个正整数N(0 < N <= 1000),表示原来队伍里有N个人(不包括HHD学长);

接下来N行,每行一个整数,表示第i个人的能力值Ai(0<=Ai<=10000)。
输出格式:

输出共N行,每行两个整数,第一个整数表示能力值,第二整数表示他们原来的位置(即重排之前他们在队伍中是第几个)。按排好队之后的先后顺序输出。
输入样例:

3
4
7
3

输出样例:

7 2
4 1
3 3

#include <stdio.h>
int main()
{
	int n;scanf("%d",&n);int a[n+1],b[n+1];
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		b[i]=i;
	}
	
	for(int i=1;i<n;i++)
	{
		for(int j=1;j<=n-i;j++)
		{
			if(a[j]<a[j+1])
			{
				int t=a[j];
				a[j]=a[j+1];
				a[j+1]=t;
				
				int s=b[j];
				b[j]=b[j+1];
				b[j+1]=s;
			}
		}
	}
	
	
	for(int i=1;i<n+1;i++)
	{
		printf("%d %d\n",a[i],b[i]);
	}
}

7-36 数组-矩阵乘法II

输入两个矩阵,输出它们相乘的结果。
输入格式:

第一行输入两个整数n,m(1<=n,m<=100),表示第一个矩阵的行和列;

接下来n行,每行m个整数,即第一个矩阵;

第n+1行输入两个整数p,q(1<=q,p<=100),表示第二个矩阵的行和列;

接下来p行,每行q个整数,即第二个矩阵。

同一行的多个整数之间以空格作为分隔符。
输出格式:

输出相乘结果,当两个矩阵不能相乘时,输出“sad”(不包括引号)。

注:计算结果有可能超过int范围。
输入样例:

3 3
1 2 3
4 5 6
7 8 9
3 4
1 2 3 4
5 6 7 8
9 10 11 12

输出样例:

38 44 50 56
83 98 113 128
128 152 176 200

#include <stdio.h>
int main()
{
	int n,m;scanf("%d%d",&n,&m);int a[n][m];
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			scanf("%d",&a[i][j]);
		}
	}
	
	
	
	int p,q;scanf("%d%d",&p,&q);int b[p][q];
	for(int i=0;i<p;i++)
	{
		for(int j=0;j<q;j++)
		{
			scanf("%d",&b[i][j]);
		}
	}
	
	
	int c[n][q];
	if(m!=p)
	printf("sad");
	else
	{
		
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<q;j++)
			{
				c[i][j]=0;
				for(int k=0;k<m;k++)
				{
					c[i][j]+=(a[i][k])*(b[k][j]);
				}
				
			}
		}
		
	}
	
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<q;j++)
		{
			printf("%d",c[i][j]);
			if(j!=q-1)
			printf(" ");
		}
		if(i!=n-1)
		printf("\n");
	}
}

7-37 数组-病人排序

医院每天会有很多病人,现在给出病人的编号(编号可能相同)和生病的严重程度(数值越大越严重),希望你将病人排序后输出(生病严重程度从大到小,相同程度的编号小的在前)。
输入格式:

第一行输入一个正整数N(1<=N<=10^3);

接下来N行,每行两个整数id,priority,分别代表病人编号和生病严重程度。
输出格式:

输出共N行,每行一个整数,即按要求排好序的病人的编号。
输入样例:

2
1 100
2 10000

输出样例:

2
1

#include <stdio.h>
int main()
{
	int n;scanf("%d",&n);int a[n],b[n];
	for(int i=0;i<n;i++)
	{
		scanf("%d%d",&a[i],&b[i]);
	}
	
	for(int i=0;i<n-1;i++)
	{
		for(int j=0;j<n-i-1;j++)
		{
			if((b[j]<b[j+1])||(b[j]==b[j+1]&&a[j]>a[j+1]))//  <保证了输出时编号小的在前
			{
				int t=b[j];
				b[j]=b[j+1];
				b[j+1]=t;//当对程度进行冒泡排序时
				
				int s=a[j];//编号也需要排序
				a[j]=a[j+1];
				a[j+1]=s;
			}
		}
	}
	
	for(int i=0;i<n;i++)
	{
		printf("%d\n",a[i]);
	}
}

7-38 数组-蜿蜒蛇形

蛇向兔子发出赛跑挑战,赛跑规定必须沿着蛇走的路径行走。

例如:当N=3时,有一个3*3的方阵形式的跑道如下所示,

       7  8  9
       6  5  4
       1  2  3 

则蛇形路径为1-2-3-4-5-6-7-8-9。因此把上面的方形跑道称之为3阶的蛇形矩阵。

现在请你根据给定的N值,帮裁判设置一个符合上述特点的蛇形矩阵跑道。
输入格式:

输入仅一个整数N(1≤n≤50)。
输出格式:

输出共N行,每行N个整数,两个整数之间用一个空格隔开,每行行末无空格。即一个N阶的蛇形矩阵。
输入样例:

4

输出样例:

16 15 14 13
9 10 11 12
8 7 6 5
1 2 3 4

#include <stdio.h>
int main()
{
	int n;scanf("%d",&n);int a[n][n];
	int t=1;
	int startrow=n-1,endcol=n-1;
	while(t<=n*n)
	{
		for(int i=0;i<=endcol;i++)
		{
			a[startrow][i]=t++;
		}
		startrow--;
		
		
		for(int i=endcol;i>=0;i--)
		{
			a[startrow][i]=t++;
		}
        startrow--;
	}
	
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(j!=n-1)
			printf("%d ",a[i][j]);
			else
			printf("%d",a[i][j]);
		}
		printf("\n");
	}
}

7-39 数组-抢回蓝爸爸

小姑凉经过扇子妈妈的训练提高了智商!于是小姑凉兴致勃勃地去找小光头,想抢回蓝爸爸。为了公平,小光头提出通过比赛来决定蓝爸爸归谁。

小光头很喜欢扫雷游戏,于是他们决定比一个跟扫雷游戏有关的比赛。

游戏规定,对于给出的地雷图,给出标定后的地雷图。(就跟扫雷游戏类似啦大家都会吧?!)谁最快得到标定好的地雷图,谁就是获胜方。小姑凉又萌萌哒向你求救了帮帮她吧~

你的任务是在已知地雷出现位置的情况下,得到各个方块中的数据。
输入格式:

输入有多组数据。

每组数据的第一行有两个数字,m,n(0<m,n<100)表示游戏中雷区的范围为m×n。

接下来m行每行有n个字符。“*” 表示有地雷,“.”表示无地雷。

(多组数据输入的结束,可以通过scanf(“%d%d”, &m, &n)的返回值为-1或EOF判断)
输出格式:

输出标记后的地雷图。有地雷的位置仍然输出“*”;没有地雷的位置输出其周围的地雷个数,即该格子周围的8个格子中有几个地雷。每组输出之间空一行,结尾不能多输出空行哦!
输入样例:

2 3



4 4


.

输出样例:


232

100
2210
1
10
1110

//二维数组,初始化元素为0
#include <stdio.h>
#include <string.h>

int count1(char a[100][100],int m,int n,int i,int j)
{
	int count=0;
	for(int dx=-1;dx<=1;dx++)
	{
		for(int dy=-1;dy<=1;dy++)//行和列的偏移量
		{
			int ni=i+dx,nj=j+dy;
			if(ni>=0&&ni<m&&nj>=0&&nj<n&&a[ni][nj]=='*')
			{
				count++;
			}
		}
	}
	return count;
}

int main()
{
	int m,n;
	while(scanf("%d%d",&m,&n)==2)
	{
		if(m==-1||n==-1)
		break;
		
		char a[100][100];
		for(int i=0;i<m;i++)
		scanf("%s",a[i]);
		
        
        for(int i=0;i<m;i++)
        {
			for(int j=0;j<n;j++)
			{
				if(a[i][j]!='*')//如果该位置不是*,输出周围地雷个数
				{
					int geshu=count1(a,m,n,i,j);
					a[i][j]=geshu+'0';//将个数转换为字符类型存储在数组中
				}
			}//如果该位置是*照常输出
		}
		
		
		for(int i=0;i<m;i++)
		{
			printf("%s\n",a[i]);
		}
		
	if(m!=0||n!=0)//当处理完一个矩阵后,如果还有矩阵需要处理,则输出一个空行
	printf("\n");
	}
}

7-40 数组-胡?福!

“阿花!结果出来了!福州大学!我考上了!”阿翔一接到录取通知书,就给这红邮件拍了张照,还没来得及用美图秀秀修一修,就迫不及待地登上QQ将照片发给了女票。阿翔心想,女票的分数比自己高了十分,自己被录取了,女票也必然是被录取了。阿翔展望着和女票同校的大学生活,心里美滋滋。这时,Nokia响了,眼见是阿花的来电,阿翔乐开了花,兴奋地接起了电话……“不!是!说!好!了!一!起!报!胡!州!大!学!的!吗!#!&(&()#)$#……”

当时阿翔就震惊了,泪流不止有如西湖的水。忽然,他的目光落到了自己珍藏的那叠英语模拟卷上,那是高考百日誓师那天阿花送给他的。“我恨H!我恨H!!我恨H!!!”说时迟那时快,阿翔抓过一支笔,对着卷子怒划!他发誓要在2015秒内把678套卷子中出现的所有H、h都改成F、f!然而250秒过去了,阿翔才改完一份考卷……阿翔认怂了,他决定向你求助。
输入格式:

第一行包含一个正整数N(0 < N <= 30),表示有N个句子。

接下来N行,每行包含一个字符串(长度不超过100,可能包含空格)。
输出格式:

输出共N行,每行为更改后的句子。每两行句子之间间隔一行。末尾没有空行。
输入样例:

2
Hu zhou
wahahahahaha

输出样例:

Fu zfou

wafafafafafa

#include <stdio.h>
#include <string.h>
int main()
{
	int n;scanf("%d",&n);
	getchar();
	for(int i=0;i<n;i++)
	{
		char a[101];
		scanf("%[^\n]",a);
		getchar();//消耗换行符
		
		int len=strlen(a);
		for(int i=0;i<len;i++)
		{
			if(a[i]=='h')
			{
				a[i]='f';
			}
			else if(a[i]=='H')
			{
				a[i]='F';
			}
		}
		a[len]='\0';
		
		printf("%s\n",a);
		
		if(i!=n-1)
		printf("\n");
	}
}

7-41 数组-字符串修改

编程课上,老师给Alice布置了一个任务,给定一个字符串,该字符串只包括拉丁字母大写字母和小写字母,让她写一段程序来实现以下几点操作:

1.删除所有的元音;

2.插入一个”.”在每个辅音字母前面;

3.替换所有大写的辅音字母为相对应的小写字母。

元音字母是‘a’、‘o’、‘e’、‘u’,‘i’或‘A’、‘O’、‘E’、‘U’、‘I’,其余的均为辅音字母。
输入格式:

输入一个字符串,长度不超过10000。
输出格式:

输出修改后的字符串。
输入样例1:

Tour

输出样例1:

.t.r

输入样例2:

codeforces

输出样例2:

.c.d.f.r.c.s

#include <stdio.h>
#include <string.h>
#include <ctype.h>

int is(char c)
{
	if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u'||c=='A'||c=='E'||c=='I'||c=='O'||c=='U')
	return 1;
	else
	return 0;
}


int main()
{
	char a[10001];
	scanf("%s",a);
	int len=strlen(a);
	for(int i=0;i<len;i++)
	{
		if(is(a[i])==0)//如果不是元音字母
		{
			printf(".%c",tolower(a[i]));//则输出对于的小写字母
		}
	}
	
}

7-43 数组-帮AC怪找子串

AC monster对Accept情有独钟。

现在希望你能找出输入的字符串中所含“Accept”的个数。

例如:WEQAcceptopiacceptwAcceptqqq中含有2个“Accept”子串。
输入格式:

输入仅一行,包含一个长度不超过10000个字符的字符串。
输出格式:

输出一个整数,表示“Accept”子串的个数。
输入样例1:

aeqweqsssaccept

输出样例1:

0

输入样例2:

Acceptiiiioac

输出样例2:

1

#include <stdio.h>
#include <string.h>
int main()
{
	char a[10001];
	scanf("%s",a);
	int len=strlen(a);
	int count=0;
	for(int i=0;i<=len;i++)
	{
		int found=1;
		for(int j=0;j<6;j++)
		{
			if(a[i+j]!="Accept"[j])//"Accept"[j]表示字符串常量"Accept"中的第j个字符
			//由j递增来检查i到i+6是否与accept相同
			{
				found=0;
				break;
			}
		}
	if(found)
	count++;
	}
	printf("%d\n",count);	
}

7-44 数组-LEN7回文串

呲溜喵很喜欢7这个数字,请你找出输入字符串中,长度为7的所有回文串。
输入格式:

输入仅一行,包括一个长度不超过1000的字符串。
输出格式:

分多行输出原字符串中所有长度为7的回文子串,每行输出一个,行末均有回车(数据保证有解)。
输入样例:

abababacacadddac

输出样例:

abababa
cadddac

#include <stdio.h>
#include <string.h>

int is(char *a,int start,int end)
{
	while(start<end)
	{
		if(a[start]!=a[end])
		return 0;
		start++;end--;
	}
	return 1;
}

int main()
{
	char a[1001];
	scanf("%s",a);
	int len=strlen(a);
	
	for(int i=0;i<=len;i++)//区间开头以1递增,间隔为6开始遍历
	{
		if(is(a,i,i+6))//先判断是否为回文数列
		{
			for(int j=i;j<i+7;j++)
			printf("%c",a[j]);
			printf("\n");
		}
		
	}
}

7-45 字符串逆序

输入一个字符串,对该字符串进行逆序,输出逆序后的字符串。
输入格式:

输入在一行中给出一个不超过80个字符长度的、以回车结束的非空字符串。
输出格式:

在一行中输出逆序后的字符串。
输入样例:

Hello World!

输出样例:

!dlroW olleH

方法一:数组实现

#include <stdio.h>
int main()
{
	char c,a[80];
	int i=0;
	while((c=getchar())!='\n')
	{
		a[i]=c;
		i++;
	}
	
	for(int j=i-1;j>=0;j--)
	{
		printf("%c",a[j]);
	}
}

方法二:引入gets及strlen

#include <stdio.h>
#include <string.h>
int main()
{
	char a[80];
	gets(a);
	
	for(int i=strlen(a)-1;i>=0;i--)
	printf("%c",a[i]);
	
}

7-46 字符串替换

本题要求编写程序,将给定字符串中的大写英文字母按以下对应规则替换:

原字母 	对应字母
A 	Z
B 	Y
C 	X
D 	W
… 	…
X 	C
Y 	B
Z 	A

输入格式:

输入在一行中给出一个不超过80个字符、并以回车结束的字符串。
输出格式:

输出在一行中给出替换完成后的字符串。
输入样例:

Only the 11 CAPItaL LeTtERS are replaced.

输出样例:

Lnly the 11 XZKRtaO OeGtVIH are replaced.

#include <stdio.h>
int main()
{
	char c,a[80],b[80];
	int i=0;
	while((c=getchar())!='\n')
	{
		a[i]=c;
		i++;
	}
	
	for(int j=0;j<=i-1;j++)
	{
		if(a[j]>='A'&&a[j]<='Z')
		{
			b[j]='A'+'Z'-a[j];
		}
		else 
		b[j]=a[j];
		
		printf("%c",b[j]);
	}
}

7-47 统计字符出现次数

本题要求编写程序,统计并输出某给定字符在给定字符串中出现的次数。
输入格式:

输入第一行给出一个以回车结束的字符串(少于80个字符);第二行输入一个字符。
输出格式:

在一行中输出给定字符在给定字符串中出现的次数。
输入样例:

programming is More fun!
m

输出样例:

2

方法一:数组实现

#include <stdio.h>
int main()
{
	char a[80],c,d;
	int i=0,count=0;
	while((c=getchar())!='\n')
	{
		a[i]=c;
		i++;
	}
	d=getchar();
	
	for(int j=i-1;j>=0;j--)
	{
		if(d==a[j])
		count++;
	}
	printf("%d",count);
}

方法二:引入gets及strlen

#include <stdio.h>
#include <string.h>
int main()
{
	char a[80],c;
	int count=0;
	
	gets(a);
	c=getchar();
	
	for(int i=0;i<strlen(a);i++)
	{
		if(a[i]==c)
		{
			count++;
		}
	}
	printf("%d",count);
}

7-48 IP地址转换

一个IP地址是用四个字节(每个字节8个位)的二进制码组成。请将32位二进制码表示的IP地址转换为十进制格式表示的IP地址输出。
输入格式:

输入在一行中给出32位二进制字符串。
输出格式:

在一行中输出十进制格式的IP地址,其由4个十进制数组成(分别对应4个8位的二进制数),中间用“.”分隔开。
输入样例:

11001100100101000001010101110010

输出样例:

204.148.21.114

#include <stdio.h>
#include <math.h>
int main()
{
	char a[33];
	int t=7;//当前处理的二进制位在8位中的位置
	int sum=0;//当前部分的十进制结果
	
	gets(a);
	for(int i=0;i<32;i++)
	{
		a[i]=a[i]-48;//将字符型的'0'~'1'转换成对应的整型数0~1
		sum+=a[i]*pow(2,t);
		
		if(t==0)//如果是8位中的最后一位
		{
		printf("%d",sum);
		t=7;
		sum=0;
		if(i!=31)
		printf(".");
		}
		else
		t--;
	}
}
  • 19
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

秋说

感谢打赏,祝你平安喜乐。

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

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

打赏作者

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

抵扣说明:

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

余额充值