第二次上机考试报告

这次上机考试第一个问题主要是对循环不熟练

例如编程的第一题

7-1 最受欢迎的菜品 (20 分)
 

某自助餐厅要求餐厅的客人在就餐后进行投票,选出一款最喜爱的菜品,每日营业结束后进行投票统计,选出投票数最多的菜品为最受欢迎的菜品。 请编写一个程序帮助餐厅快速完成这个统计工作。

输入格式:

第1行中给出一个正整数n(不超出1000),表示菜品的数量,每个菜品使用1~n进行编号。 第2行输入若干以空格间隔的正整数,表示客人投出的最喜爱的菜品编号,以键盘结束符^Z或文件结束符结束输入。

输出格式:

每行输出一个最受欢迎的菜品编号和得票数。 菜品编号和得票数间隔1个空格。如果有并列的最受欢迎的菜品,则按编号从小到大的顺序输出每一个菜品,每个菜品占一行。

输入样例:

10
6 8 5 8 9 3 6 6 8 2 1 4 7 2 8 3 8 9 6 3 8 10 6 6
 
结尾无空行
 

输出样例:

6 6
8 6
 
结尾无空行
 
这是我原来的代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int sum;
	scanf("%d",&sum);
	int c;
	int b[1000];
	memset(b,0,sizeof(b));
	int max=-1,maxi;
	while(scanf("%d",&c)!=EOF)
	{
	
		if(c>=1&&c<=10)
		{
			b[c]++;
			if(b[c]>max)
			{
			max=b[c];
			maxi=c;
			}
		
		}
	}
	
	printf("%d %d",maxi,max);
}
 
 没有对输出相同的菜品进行全部输出,这个纯属当时大意了并且没有及时的对错误进行编译调试
这是我修改后的代码:
查看代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	scanf("%d",&n);
	int i,a[1000];
	for(i=0;i<n+1;i++)
	{
		a[i]=0;
	}
	while(scanf("%d",&i)!=EOF){
		a[i]++;
	}
	int max=a[1];
	for(i=1;i<n+1;i++){
		if(max<a[i]){
			max=a[i];
		}
	}
	for(i=1;i<n+1;i++)	
	{
		if(max==a[i])
			printf("%d %d\n",i,a[i]);
		}
		return 0;
	
 } 
 第二个问题呢是字符串的移动:
 
 
7-2 字符串循环左移 (20 分)
 

输入一个字符串和一个非负整数,要求将字符串循环左移次。

输入格式:

输入在第1行中给出一个不超过100个字符长度的、以回车结束的非空字符串;第2行给出非负整数

输出格式:

在一行中输出循环左移次后的字符串。

输入样例:

Hello World!
2
 
结尾无空行
 

输出样例:

llo World!He
 
结尾无空行
我直接写上我修改后的代码,因为我的错误是没有对N大于字符串长度的情况进行讨论:
查看代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
	char str[100];
	int i=0,j;
	while((str[i]=getchar())!='\n')
	i++;
	str[i]='\0';
	int l=i;
	char a[100];
	int n;
	scanf("%d",&n);
	n%=l; 
	for(i=0;i<l;i++)
	{
		a[i]=str[i];
	}

/*	for(int j=0;j<l;j++)
	{
		if((j+n)>=l)
	{
			str[j]=str[j+n-l];
			printf("str[%d]=str[%d]=%c\n",j,j+n-l,str[j+n-l]);
		
	}	
	}*/
	
	for(j=0;j<l;j++)
	{
		if((j+n)<l)
		str[j]=str[j+n];
	}
	int m;
	for(j=0;j<l;j++)
	{
		if((j+n)>=l)
		{
			m=j;
		break;
		}
	
		
	}
	for(int k=0;k<n;k++)
	{
		str[m]=a[k];
		m++;
	}
	for(i=0;i<l;i++)
	printf("%c",str[i]);
	
}
 一定要注意n%=l,这个不能省,不然题一直过不了,就是因为这个,导致了第三题完全没时间做,所以对程序的调试很重要,在接下来的练习中,我要加强这方面的练习。
接下来的这道题自己曾经打过,但是疏于练习,理解,所以没能很快想出来:
7-3 顺时针矩阵 (30 分)
读入20内正整数正整数n,输出顺时针分布的矩阵。矩阵内容为1,2,。。。到n*n。

输入格式:
每个实例包含一个20内正整数。

输出格式:
顺时针分布的矩阵,每个数据占4位。

输入样例:
7
结尾无空行
输出样例:
  19  20  21  22  23  24   1
  18  37  38  39  40  25   2
  17  36  47  48  41  26   3
  16  35  46  49  42  27   4
  15  34  45  44  43  28   5
  14  33  32  31  30  29   6
  13  12  11  10   9   8   7
结尾无空行
 上代码!
查看代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int dx[4]={1,0,-1,0};
	int dy[4]={0,-1,0,1}; 
	int n,i,j;
	scanf("%d",&n);
	int a[22][22];
	for(i=0;i<=n+1;i++)
	{
		for(j=0;j<=n+1;j++)
		a[i][j]=-1;
	}
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=n;j++)
		a[i][j]=0;
	}i=1,j=n;int d=0;
	for(int k=1;k<=n*n;k++)
	{
		a[i][j]=k;
		if(a[i+dx[d]][j+dy[d]]!=0)d=(++d)%4;
		i=i+dx[d];
		j=j+dy[d]; 
	}
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=n;j++)
		{
		cout<<setw(4)<<a[i][j];
		
		}	printf("\n");
	}
}
 要注意开头的int dx[4]={1,0,-1,0};int dy[4]={0,-1,0,1}; 这两个数组分别控制的是数组X,Y的移动,根据题意,先是Y不动,X加一,所以是1,0,接下来是X不动,Y减一,所以是0,-1,以此类推,还要注意的是要将数组边界的值赋值为-1,当一直移动到不为零时,就会改变方向,数组元素始终自增
反思:
遇到这类数组输出的问题时一定不能慌,要冷静分析,毕竟这些都是自己学过的内容,要将不会的问题化解为已有的知识。接下来还得多练习有关数组输出的题目
递归的问题:
看看我第一遍都写了个啥
#include<stdio.h>
void Porder(int n);
int main()
{
    int num;
    scanf("%d",&num);
    Porder(num);
    return 0;
}

void Porder(int n){
    if ( 
1分
 ) {
        Porder ( 
1分
 );
    }
    printf ( 
1分
 ) ;
}
 

如:输入: 123输出:

1

2

3

提示:每行数字后都有换行符。

递归这类问题最好画一个图来解决

这里的%10在函数回溯返回时得到当前参数“个位”的, 以n = 123为例,我们看看函数的调用过程:
每一层代表一个函数,左侧代表入栈,右侧表示出栈,程序从main()函数开始,最后回到main函数。左侧方块上的n表示当前函数的参数n,往下依次/10,所以n为123,12,1。

正确答案应该为 :n>0  n/10 "%d\n",n

反思:学习递归时一定要弄明白函数的调用过程,特别是一些相对复杂的问题,例如输出全排列,倒杨辉三角,九连环问题等。

接下来我将在以后的学习中更加深入的学习,不能只掌握表面,更要融会贯通。

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2021-12-10 19:18  fsknsl  阅读(108)  评论(0编辑  收藏  举报