2019 计算机专业课堂测验1

哇,这个签到题是真的烦,沉迷于其中无法自拔。这次考试的失误如下:
1.沉迷签到题,主要是后面的不想写了,其实写得出来,自己不想思考,不会类比推理,从做过的题找经验。
2.旁边有人抱我的腿,托我后腿,以后得独立思考,不要靠大佬,更不要靠小白。

1341

请回答一下的问题:

1常量1e6是什么类型?
unsigned int
int
float
double
2已知21!=51,090,942,171,709,440,000,能用下列哪种数据类型存储?
int
long long
double
以上皆不能
3下列关于表达式左值说法错误的是?
变量名表达式是左值的
自增运算要求操作数是左值的
指针的间接访问表达式是左值的
前缀自增运算表达式是左值的
4.下面关于函数说法错误的是?
函数的形式参数是局部变量
局部变量在栈区分配空间
函数类型就是函数返回值的类型
函数体内部可以调用本函数
5下面关于指针说法错误的是:
两个指针相减等于两个指针指向的地址值的差值
指针间接访问时,根据指针的类型确定解析方式
int *p[4],p是一个int型指针数组
可以将函数名赋值给函数指针
请注意,本题1000分,每错误提交一次,减50分,最少得0分。

输入
无输入

输出
输出一行,表示问题的结果,为5个问题的选项,每个选项都是大写英文字母ABCD中的一个。

样例输入
样例输出
AAAAA

答案:DDDBA

1343

有n个位置按顺时钟排列成一个圆,分别编号从1∼n。一只青蛙最开始在1号位置上,它每次可以跳往与之相隔k个位置的位置上。比如,n=5,k=2时, 青蛙从位置1可以按逆时钟方向跳到位置3,也可以按顺时钟方向跳到位置4。请问这只青蛙能跳到所有的位置上吗?

输入
第一行输入一个整数 T(1≤T≤1000),表示样例的个数。 以后每行一个样例,为两个整数n(1≤n≤109),k(0≤k≤n−2)。

输出
每行输出一个样例的结果。如果青蛙可以到达所有位置,输出"Yes",否则输出"No".

样例输入
2
5 2
4 1
样例输出
Yes
No
样例解释
第一个样例,青蛙一直按顺时钟跳,依次的位置为 1,4,2,5,3; 第二个样例,青蛙只能跳到1,3两个位置。

思路:判断gcd(n,k+1)是否为1即可。

1345

我们将素数从小到大依次书写,可以得到一个字符串"23571113⋯",已知一个数码d(0≤d≤9),求字符串在区间[L,R]之间的多少个d?

输入
第一行是一个整数T(1≤T≤10000),表示样例的个数。 每个样例是一行, 为3个整数,区间L,R,(1≤L≤R≤1000000)和数码d。 区间从1开始计数。

输出
每行输出一个样例的结果。

样例输入
2
1 8 1
1 8 4
样例输出
3
0

思路:经典套路,筛法加前缀和。

#include
#include
#define max 2100000 
int a[max+11];
int x[11][max/2+11];
char s[max/2+11];  //全部初始化为串结束符。
int main(){
     
	int t,l,r,i,j,d,k,flag=0,p,q;
	for(i=2;i*i<=max;i++){
     
		if(!a[i]){
     
			for(j=i*i;j<=max;j+=i)  a[j]=1;
		}
	}
	for(i=2;i<=max;i++){
     
		if(!a[i]){
     
			p=i;
			k=0;
			while(p){
     
				p/=10;
				k++;
			}
			p=i;
			while(p){
     
				s[flag+k-1]=p%10+'0';  //这里赋值了多少个字符,与strlen是对应的。 
				flag++;
				k-=2;
				p/=10;
			}
		}
	}
	x[2][0]=1;
	for(i=1;i<flag;i++){
       //这里用strlen就运行不下去了,为啥? 
		if(s[i]=='0')  x[0][i]+=(x[0][i-1]+1);  //用二维数组就可以存对应的d值时的数组。 
		else  x[0][i]=x[0][i-1];
		if(s[i]=='1')  x[1][i]+=(x[1][i-1]+1);  //这里不用写的这么复杂,再写个循环就好啦啊! 
		else  x[1][i]=x[1][i-1];
		if(s[i]=='2')  x[2][i]+=(x[2][i-1]+1);
		else  x[2][i]=x[2][i-1];
		if(s[i]=='3')  x[3][i]+=(x[3][i-1]+1);
		else  x[3][i]=x[3][i-1];
		if(s[i]=='4')  x[4][i]+=(x[4][i-1]+1);
		else  x[4][i]=x[4][i-1];
		if(s[i]=='5')  x[5][i]+=(x[5][i-1]+1);
		else  x[5][i]=x[5][i-1];
		if(s[i]=='6')  x[6][i]+=(x[6][i-1]+1);
		else  x[6][i]=x[6][i-1];
		if(s[i]=='7')  x[7][i]+=(x[7][i-1]+1);
		else  x[7][i]=x[7][i-1];
		if(s[i]=='8')  x[8][i]+=(x[8][i-1]+1);
		else  x[8][i]=x[8][i-1];
		if(s[i]=='9')  x[9][i]+=(x[9][i-1]+1);
		else  x[9][i]=x[9][i-1];
	}
	scanf("%d",&t);
	while(t--){
     
		scanf("%d%d%d",&l,&r,&d);
		if(s[l-1]==d+'0'){
     
			if(l==r)  printf("0\n");
			else  printf("%d\n",x[d][r-1]-x[d][l-1]+1);
		}  //不能直接写=='d',这样子是等于字母d,而不是变量d。 
		else  printf("%d\n",x[d][r-1]-x[d][l-1]);	//这里写成x[d][r-1]-x[d][l-2]即可。
		//printf("%d%d\n",x[d][r-1],x[d][l-1]);
	} 
	return 0;
}

注意:前缀和只要写x【b】-x【(a-1)】即可。

1346 小球

这道题设计到浮点数,有许多要注意的地方。

小球
题目描述
有一个水平的光滑轨道,轨道长度为L,在轨道不同的地方有一些完全相同的刚体小球. 由于小球半径远小于轨道长度,我们可以把它们当做一些质点。每个小球有其初始的速度vi,方向平行于轨道。 当小球相碰时会发生完全弹性碰撞(两球碰撞后,速度发生交换)。 请你计算一下,这些小球最晚多少时间都能滑出轨道(到达轨道两端即视为滑出轨道)?。

输入
第一行是一个整数T(1≤T≤100),表示样例的个数。 每个样例的第一行是两个整数n(1≤n≤100),L(10≤L≤10000),分别表示小球的个数,和轨道的长度(单位:米)。 以后的n行,每行两个整数x(1≤x≤L−1),v(−100≤v≤100),分别表示某个小球距离轨道左端的距离(单位:米)和初始的速度(单位:米/秒),如果速度值为负表示速度方向朝向轨道的左端,否则速度方向为右端。输入数据保证所有的小球初始在不同的位置上。

输出
每行输出一个样例的结果,单位为秒,保留小数点后1位。如果无法全部滑出轨道,输出"Impossible"。

样例输入
2
2 11
1 2
2 5
3 11
1 5
10 -5
5 2
样例输出
5.0
3.0

//思路:其实弹性碰撞虽然速度交换了,其实可以看做碰后的另一个小球
//在帮他跑。
#include
#define eps 1e-6
#include
int main(){
     
	int i,t,flag,q,n;
	double l,x,v,max,p;
	//for(i=0;i<11;i++)  printf("%c",s[i]);
	//printf("%lf",eps);
	scanf("%d",&t);
	while(t--){
       //t不能是浮点数,因为有精度误差
		flag=0;
		scanf("%d%lf",&n,&l);
		scanf("%lf%lf",&x,&v);
		if(v>0.0)  max=(l-x)/v;  //这种v>0.0还是没关系,浮点数就这么写可以
		else if(fabs(v-0.0)<eps){
     
			flag=1;
			max=0.0;
		}
		else  max=x/(-v);
		for(i=2;i<=n;i++){
      //n也不能是浮点数,如1.99999999这种情况。
			scanf("%lf%lf",&x,&v);
			if(v>0.0)  p=(l-x)/v;
			else if(fabs(v-0.0)<eps){
      //浮点判断相等就一定要这么写了,fabs事绝对值
				flag=1;
				continue;
			}
			else  p=x/(-v);
			if(p>max)  max=p;
		}
		if(flag)  printf("Impossible\n");
		else printf("%.1f\n",max);	//除了double输入是lf,其余都是f。 
	}
	return 0;
} 

1347 消消乐

这道模拟题又是写了很久,差不多快写出来了
只是因为一开始的输入写错了。
还有就是感叹一件事,现在的脑力真不如从前了,连续未间断想了两个小时,脑子已经想不动了,得休息一下了。
主要是一开始输入弄错了,要想从序号1开始输入,地址加1就好了,如s+1;
题目描述
你有若干个彩球排成一列,你可以交换相邻的两个球。 如果出现含被交换球的3个或者以上的的同颜色彩球,那么这些彩球就会消失,右边的彩球会向左边靠拢填满空间。 现在给你一个操作的序列,请依次输出每次操作后的彩球序列。

输入
第一行是一个整数T(1≤T≤100),表示样例的个数。 每个样例包含两行,第一行是一个字符串,长度不超过30,只含大写字母’A’-‘C’,表示不同字母表示不同颜色的球。第二行开始是一个整数n(1≤n≤10),表示操作的个数,以后n个整数ai表示将ai和ai+1交换。输入数据保证是合法的操作。

输出
每个样例的每行输出一个操作后彩球的状况,每个样例最后输出一个空行。

样例输入
4
AABABBB
1 3
AAAABBBBC
2 4 4
AAAAAA
1 2
AABAABBB
2 3 1
样例输出
Over

AAABABBBC
C

Over

BABBB
A

/*思路:先判断交换的两个小球是否一样,一样的话,就要往两边消
不一样就分别往两边消。用一个数组来存字符数组的状态。 
在想问题时,优先考虑方便自己做出来,其次是优化。 */
#include
#include
int main(){
     
	int t,y[33],n,a,i,j,k,l,flag,p;
	char x[33]={
     '0'};char e;
	scanf("%d",&t);
	while(t--){
     
		for(i=0;i<=32;i++)  y[i]=1;
		scanf("%s",x);
	 	//我之前用的是那个从1开始每个字符输入,然后遇回车break;
		//再在后面接一个串结束符,这样子输入极容易出错,建议不用。 
		//这个输入有问题。我就想从1开始输入,有啥好法子吗? 有,地址+1; 
		//printf("%d\n",strlen(x));
		scanf("%d",&n);
		for(i=1;i<=n;i++){
     
			scanf("%d",&a);//y是记录x状态的,x一旦改变,y也就要跟着改变! 
			a=a-1;
			e=x[a];x[a]=x[a+1];x[a+1]=e;
			p=0;l=strlen(x); 
			if(x[a]==x[a+1]){
     
				for(j=a;j>=1;j--){
     
					if(x[j]!=x[j-1])  break;
				}
				flag=j;
				for(j=a+1;j<=l-2;j++){
     
					if(x[j]!=x[j+1])  break;
				}
				if(j-flag>=2){
     
					for(k=flag;k<=j;k++)  y[k]=0;
				}
			}
			else{
     
				for(j=a;j>=1;j--){
     
					if(x[j]!=x[j-1])  break;
				}
				if(a-j>=2){
     
					for(k=j;k<=a;k++)  y[k]=0;
				}
				for(j=a+1;j<=l-2;j++){
     
					if(x[j]!=x[j+1])  break;
				}
				if(j-a-1>=2){
     
					for(k=a+1;k<=j;k++)  y[k]=0;
				}
			}
			for(j=0;j<l;j++){
     
				if(y[j]){
     
					x[p]=x[j];
					p++;
				}
			}
			x[p]=0;
			if(p==0)  printf("Over\n");
			else{
     
				for(j=0;j<p;j++)  y[j]=1;
				puts(x);
			}
		}
		printf("\n");
	}
	return 0;
}

1348 数字

数字
题目描述
正整数n和k,你每一步,按下列规则执行

如果n的尾部为数码0,就去掉尾部的数码0,直到尾部数码不为0。
否则,将 n = n - k
不断迭代,直到 n < k 。

求一共需要迭代多少步及最后的n值。

输入
第一行是一个整数T(1≤T≤1000),表示样例的个数。 以后每行一个样例,为两个整数n(1≤n≤109),k(1≤k≤104)

输出
每行输出一个样例的结果,包括两个整数,即步数和最后的n值。

样例输入
4
112 3
203 3
333 3
1000000000 2
样例输出
5 1
2 2
5 0
1 1

思路:要让n的个位数变为0,其实看k与1~9相乘的个位数能否与n的个位数相等就可以了。

#include
int main(){
	int flag,mark,t,n,k,sum=0,num[11]={0},i,j;
	scanf("%d",&t);
	while(t--){
		sum=0;
		scanf("%d%d",&n,&k);
		for(i=1;i<=9;i++)  num[i]=k*i%10;
		while(n>=k){
			flag=n%10;
			if(flag==0){
				while(n%10==0)  n/=10;
				sum++;
				continue;
			}
			mark=0;
			for(i=1;i<=9;i++){
				if(num[i]==flag){
					mark=i;
					break;	
				}    
			}
			if(mark==0){
				sum+=n/k;
				n=n-n/k*k;
				break;
			}
			else{
				if(n>=k*mark){
					n-=mark*k;
					sum+=mark;
				}
				else{
					sum+=n/k;
					n=n-n/k*k;
					break;	
				}
			}
		}
		printf("%d %d\n",sum,n);
	}
	return 0;	
}

你可能感兴趣的:(#,128,模拟考试)