题目一

7-1 参考书 (100 分)

某次考试是开卷考试。老师规定,纸质的资料(以下统一称为参考书)可以随便带,或者说只要你背得动想带多少本参考书都行。于是同学们就开始准备参考书了。就在考试前一天,老师觉得大家准备的参考书实在是太多了,就突然改了主意。新规则规定,所带所有参考书的总页数不能超过1000页。这下小明同学犯愁了,因为他准备的参考书总页数远远超过1000。现在请你写一段C程序帮小明算一下他这次考试最多能带几本参考书。

输入格式:

共2行,第1行一个整数n(5<n<100),代表小明同学准备的参考书的总数,第2行是n个用空格分隔的整数,分别代表小明同学每本参考书的页数(每本书的页数大于0,小于1000,测试数据保证所有书的总页数超过1000)。

输出格式:

只有1行,一个整数,表示小明最多可以带的参考书的本数。

输入样例:

10
100 125 200 234 300 321 400 487 500 526

结尾无空行

输出样例:

5

参考答案

#include<stdio.h>
int main(){
	int a[101]={0};
	int n;
	int i,j,temp;
	int m,x;
	m=0;
	
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	
	for(i=0;i<n;i++){
		for(j=0;j<n;j++){
			if(a[j]>a[j+1])
			{
				temp=a[j+1];
				a[j+1]=a[j];
				a[j]=temp;
			}
		}
	}
	
	for(i=0;i<n;i++){
		m=m+a[i];
		if(m>1000) {x=i;break;}
	}
	
	printf("%d",x-1);
	return 0;
}

7-2 实验7_6_数组交换 (100 分)

设有整数数组A和B,它们长度均为n。A数组中的元素为任意整数,不超过int型数据范围。B数组中元素的值互不相同,且取值介于0至n-1之间。现要求按数组B的内容调整A中数据的次序,比如当B[0]=9时,则要求将A[0]的内容与A[9]互换。

输入格式:

首先输入一个整数n(0<n<=10),代表数组A、B元素的个数。然后输入n个整数代表数组A中的元素。最后输入 n个整数代表数组B中的元素,注意B中元素的要求。测试用例保证所有整数可以用int存储。

输出格式:

调整后A数组的内容,数与数之间用空格分开,注意第n个数后没有空格而是换行符。

输入样例:

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

输出样例:

3 9 4 2 5 12 10 11 7 8

参考答案

#include<stdio.h>
int main(){
	int n;
	int a[11]={0};
	int b[11]={0};
	int i,temp;
	int x;
	
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	for(i=0;i<n;i++){
		scanf("%d",&b[i]);
	}
	for(i=0;i<n;i++){
		x=b[i];
		temp=a[x];
		a[x]=a[i];
		a[i]=temp;
	}
	for(i=0;i<n;i++){
		if(i==n-1) printf("%d\n",a[i]);
		else printf("%d ",a[i]);
	}
	return 0;
}

7-3 字符串输出 (100 分)

按要求输出字符串。

输入格式:

第一行为一个字符c(只可能是大写字符或小写字符) 第二行为一个整数n(1<n<20),代表测试数据组数。 后边是n行,每行一个字符串(字符串中只包含大写字母或小写字母,且长度小于60),为n组测试数据。

输出格式:

若干行(至少一行),每行对应输入的n行字符串,如果c在该行字符串中出现过两次或两次以上(无论大写或小写只要字母一样就算出现一次),则该字符串被输出,否则该字符串不能被输出。如果输出的字符串超过一个,则每个字符串占一行且后输入的先输出。

输入样例:

c
2
TaNgvFRLJUvgnLjdKvaacumgGtOl
dcaLySkOWzYyAYKBOyfIIxOZCi

结尾无空行

输出样例:

dcaLySkOWzYyAYKBOyfIIxOZCi

参考答案

#include<stdio.h>
#include<string.h>
int main(){
	char c[20][61],b[2];
	int n,len;
	int a[20]={0};

	scanf("%c",&b[0]);
	scanf("%d",&n);

	for(int i=0;i<n;i++){
		scanf("%s",c[i]);
		len=strlen(c[i]);
		for(int j=0;j<len;j++){
			if((c[i][j]==b[0])||(c[i][j]==b[0]+32)||(c[i][j]==b[0]-32)) a[i]++;
		}
		
	}
	for(int i=n-1;i>=0;i--){
		if(a[i]>=2) printf("%s\n",c[i]);
	}
	
}

7-4 实验9_2_身份证号码最后一位 (100 分)

身份证编码规则如下:根据〖中华人民共和国国家标准GB11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。

顺序码(身份证第十五位到十七位)是县级公安机关所辖派出所的分配码,每个派出所分配码为10个连续号码,例如“000-009”或“060-069”,其中单数为男性分配码,双数为女性分配码,如遇同年同月同日有两人以上时顺延第二、第三、第四、第五个分配码。如:005的就是个男性,而且和他同年月日生的男性至少有两个,他们的后四位是001*和003*。分配顺序码中“999、998、997、996”四个顺序号分别为男女性百岁以上老人专用的特定编号。 校验码(身份证最后一位)是根据前面十七位数字码,按照ISO7064:1983.MOD11-2校验码计算出来的检验码。

从1999年10月1日起,全国实行公民身份证号码制度,居民身份证编号由原15位升至18位。前6位为地址码;第七位至14位为出生日期码,此码由6位数改为8位数,其中年份用4位数表示;第15位至17位为顺序码,取消了顺序码中对百岁老人使用的特定编号;第十八位为校验码,主要是为了校验计算机输入公民身份证号码的前17位数字是否正确,其取值范围是0至10,当值等于10时,用罗马数字符X表示。

计算方法

1、将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2。

2、将这17位数字和系数相乘的结果相加。

3、用加出来和除以11,看余数是多少?

4、余数只可能有0-1-2-3-4-5-6-7-8-9-10这11个数字。其分别对应的最后一位身份证的号码为1-0-X -9-8-7-6-5-4-3-2。(即余数0对应1,余数1对应0,余数2对应X...)

5、通过上面得知如果余数是3,就会在身份证的第18位数字上出现的是9。如果对应的数字是2,身份证的最后一位号码就是罗马数字X。

例如:某男性的身份证号码为【53010219200508011X】, 我们看看这个身份证是不是符合计算规则的身份证。

首先我们得出前17位的乘积和【(5*7)+(3*9)+(0*10)+(1*5)+(0*8)+(2*4)+(1*2)+(9*1)+(2*6)+(0*3)+(0*7)+(5*9)+(0*10)+(8*5)+(0*8)+(1*4)+(1*2)】是189,然后用189除以11得出的结果是189÷11=17余下2,187÷11=17,还剩下2不能被除尽,也就是说其余数是2。最后通过对应规则就可以知道余数2对应的检验码是X。所以,可以判定这是一个正确的身份证号码。

现在请你写一段程序来判断一个身份证号码的最后一位是否与上述规则相符。

输入格式:

第一行一个整数T(0<T<100),表示有T行测试数据。后边是T行每行是一个18位的身份证号码(测试数据前17位保证符合身份证号码的要求,罗马数字X就是大写的英文字母X)。

输出格式:

T行,与输入的T行测试数据相对应,如果该行测试数据最后一位符合所述算法则输出right,否则输出wrong。

输入样例:

2
34052419800101001X
310105199412049278

输出样例:

right
wrong

参考答案

#include<stdio.h>
#include<string.h>
int main(){
	int t,i,j,temp,temp2;
	char s[19];
	int n,test;
	
	scanf("%d",&t);
	
	for(j=1;j<=t;j++){	
		n=0;
		//for(i=0;i<=18;i++){
		 scanf("%s",s);
			//输入18位身份证
		//}
		
		for(i=0;i<=17;i++){
			temp=s[i]-'0';//18位身份证具体每一位数字
			
			if(i==0) n=n+(temp*7);
			if(i==1) n=n+temp*9;
			if(i==2) n=n+temp*10;
			if(i==3) n=n+temp*5;
			if(i==4) n=n+temp*8;
			if(i==5) n=n+temp*4;
			if(i==6) n=n+temp*2;
			if(i==7) n=n+temp*1;
			if(i==8) n=n+temp*6;
			if(i==9) n=n+temp*3;
			if(i==10) n=n+temp*7;
			if(i==11) n=n+temp*9;
			if(i==12) n=n+temp*10;
			if(i==13) n=n+temp*5;
			if(i==14) n=n+temp*8;
			if(i==15) n=n+temp*4;
			if(i==16) n=n+temp*2;	
		}
		temp2=s[17]-'0';//第18位数字
		test=n%11; 
		
		
			if(test==0&&temp2==1) printf("right\n");
			else if(test==1&&temp2==0) printf("right\n");
			else if(test==2&&temp2==40) printf("right\n");
			else if(test==3&&temp2==9) printf("right\n");
			else if(test==4&&temp2==8) printf("right\n");
			else if(test==5&&temp2==7) printf("right\n");
			else if(test==6&&temp2==6) printf("right\n");
			else if(test==7&&temp2==5) printf("right\n");
			else if(test==8&&temp2==4) printf("right\n");
			else if(test==9&&temp2==3) printf("right\n");
			else if(test==10&&temp2==2) printf("right\n");
			else printf("wrong\n");
		
		
	}

}

7-5 安全密码 (100 分)

某网站规定注册账号时密码必须达到一定强度才可以。他们规定密码长度至少6位,数字、大写字母、小写字母、符号(~!@#$%^&*()[]}{|<>?/.,:"';)这四类中至少包含三类才合格。现在请你写一段程序来判断一个密码是否合格。

输入格式:

第一行为一个整数n(0<n<10),代表测试用例组数, 后边是n行测试用例,每行为一个长度不超过30的字符串。

输出格式:

共n行,与输入的n行测试用例相对应,如果密码合格则输出yes,否则输出no。

输入样例:

2
123456
Hello2020.

输出样例:

no
yes

参考答案

#include<stdio.h>
#include<string.h>
int judge(int n);
int main()
{
	int n;
	int a[10];
	
	scanf("%d",&n);
	
	for(int i=1;i<=n;i++){
		a[i]=judge(i);	
	}
	for(int i=1;i<=n;i++){
		if(a[i]==1) printf("yes\n");
		else printf("no\n");	
	}
	
	
	
}

int judge(int n){
	int len;
	int a=0,b=0,c=0,d=0;
	char pass[30];
	
    scanf("%s",pass);
	len=strlen(pass);
	
	if(len<6) return 0;
	else{
		for(int i=0;i<len;i++){
			if(pass[i]>=48&&pass[i]<=57) a=1;
			if(pass[i]>=97&&pass[i]<=122) b=1;
			if(pass[i]>=65&&pass[i]<=90) c=1;
			if((pass[i]>=33&&pass[i]<=42)||pass[i]==44||pass[i]==46||pass[i]==47||(pass[i]>=58&&pass[i]<=60)||(pass[i]>=62&&pass[i]<=64)||(pass[i]>=91&&pass[i]<=94)||(pass[i]>=123&&pass[i]<=126)) d=1;
				
		}
	if(a+b+c+d>=3) return 1;
	else  return 0;
	}
	
}

7-6 北京市机动车网上自选牌号的正误鉴别 (100 分)

2009年3月9日开始,北京市交通管理局正式推出北京市机动车网上自选牌号业务,极大的方便了新购车的市民自选中意的新车牌照号的需求。根据国家制定的机动车号牌号码标准,一辆机动车的号牌号码由七位字符组成,前两位是号牌号码发牌机关代码,后五位是具体号牌号码。主管部门在具体操作上又出台了以下规定:机动车所有人网上选号的号牌号码发牌机关代码为“京N”或者“京Y”。后面的五位号牌号码的最后一位必须为数字,其余四位有且必须有两位为英文字母(但字母I和O不可用),也就是说英文字母有且只有两个,不能多也不能少。例如:京NAB999、京NC9D99、京NE99F9、京N9GH99、京N9J9K9、京N99LM9、京YNB999、京YP9D99、京YZ99F9号码都是正确的。你能据此编写一个程序来检测给定的号牌号码是否符合上述规定吗?

输入格式:

第一行为一个整数T(0<T<=100),代表测试用例组数,后边是T组测试用例,每个用例占一行,为含有号牌号码最后五位的字符内容(不会包含空格、回车等空白符)。

输出格式:

为T行,每行对应输入的测试用例,如果检测认为测试用例符合规定则输出“yes:”并后跟对应的号牌号码(如果号牌中字母为小写字母,请转换为大写字母输出),如果检测认为不符合规定则输出“no.”(不含双引号本身)。注意,如果号牌中包含有非法字符(也就是不是字母也不是数字的字符),也认为不符合规定。

输入样例:

2
K00a1
aBc12

结尾无空行

输出样例:

在这里给出相应的输出。例如:

yes:K00A1
no.

参考答案:

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

int main()
{
	int t,len;
	int a=0,b=0;
	
	char pass[6];
	
	scanf("%d",&t);
	
	for(int i=1;i<=t;i++){
		a=0;b=0;
		
		scanf("%s",pass);
		len=strlen(pass);
		
		if(len!=5) {printf("no.\n");continue;}
		if((pass[4]-'0')<0||(pass[4]-'0')>9) {printf("no.\n");continue;}
		if((pass[0]=='I')||(pass[0]=='O')||(pass[0]=='i')||(pass[0]=='o')||(pass[1]=='I')||(pass[1]=='O')||(pass[1]=='i')||(pass[1]=='o')||(pass[2]=='I')||(pass[2]=='O')||(pass[2]=='i')||(pass[2]=='o')||(pass[3]=='I')||(pass[3]=='O')||(pass[3]=='i')||(pass[3]=='o')) {printf("no.\n");continue;}
		else{
			for(int i=0;i<len;i++){
					if((pass[i]-'0')>=0&&(pass[i]-'0')<=9) a++;
					else if((pass[i]-'a')>=0&&(pass[i]-'a')<=25) {b++;pass[i]=pass[i]-32;}
					else if((pass[i]-'A')>=0&&(pass[i]-'A')<=25) b++;}
			
	
				if(a==3&&b==2) printf("yes:%s\n",pass);	
				else printf("no.\n");	
		}	
	}
}

7-7 九宫格密码 (100 分)

随着智能手机的普及,各种应用也层出不穷,安卓的九宫格密码就是其中之一。安卓的九宫格密码可以看做是3×3点阵中的一条路径,只要你在画的时候,不经过重复的点,同时不跳过途中必须要经过的点,那么这条路径几乎是无所不能的。

android 输入数字跟点_职场和发展

现在就请你写一段程序将这条路经转换成相应的密码。我们这里做一个限制,就是在画这条路经时,从一个点到另一个点,无论是横向还是纵向每次最多移动一个格。也就是说如果我们按程序设计的习惯用(0,0)表示左上角的点,那么从它出发可能的移动只有三个,即可以移动到(0,1)、(1,0)和(1,1)三个点,而不能像真实的九宫格密码那样可以移动到(1,2)(2,1)等点。

输入格式:

为两行,第一行为两个整数,代表起始点坐标,其中(0,0)代表左上角,(0,1)代表第一行中间,(0,2)代表右上角,(1,0)代表第二行最左等等,其余以此规律类推。第二行为长度最长为8的字符串,代表每次移动的方向。字符串中仅可能含有 ‘1’、 ‘2’、 ‘3’、 ‘4’、 ‘6’、 ‘7’、 ‘8’、 ‘9’八种字符,其中‘1’代表向左下移动、‘2’代表向下移动、‘3’代表向右下移动,‘4’代表向左移动,‘6’代表向右移动、‘7’代表向左上移动、‘8’代表向上移动、‘9’代表向右上移动。输入保证合法,不存在移到九宫格以外的可能。

输出格式:

仅一行,为上述输入的路径所代表的密码。其中每个点所代表的数字同手机键盘,也就是说(0,0)点为1,(0,1)点为2,(0,2)点为3,(1,0)点为4等等。

输入样例:

0 0
661166

输出样例:

在这里给出相应的输出。例如:

1235789

参考答案:

#include<stdio.h>
#include<string.h>
int move(int n,int start);
int f(int x,int y);
int main(){
	int b[9];
	int x,y,len,n,start;
	char c[9];
	
	scanf("%d%d",&x,&y);
	start=f(x,y);
	
	
	scanf("%s",&c);
	len=strlen(c);
	printf("%d",start);
	for(int i=0;i<len;i++){
		n=c[i]-'0';
		b[i]=move(n,start);
		start=b[i];
		
	}
	
	for(int i=0;i<len;i++){
		printf("%d",b[i]);
	}
	
		
}
int f(int x,int y){
	if(x==0&&y==0) return 1;
	if(x==0&&y==1) return 2;
	if(x==0&&y==2) return 3;
	if(x==1&&y==0) return 4;
	if(x==1&&y==1) return 5;
	if(x==1&&y==2) return 6;
	if(x==2&&y==0) return 7;
	if(x==2&&y==1) return 8;
	if(x==2&&y==2) return 9;	
}

int move(int n,int start){
	if(n==1) return (start+2);
	if(n==2) return (start+3);
	if(n==3) return (start+4);
	if(n==4) return (start-1);
	if(n==6) return (start+1);
	if(n==7) return (start-4);
	if(n==8) return (start-3);
	if(n==9) return (start-2);
}

7-8 实验9_1_括号匹配 (100 分)

任意给定一个字符串,字符串中包含除了空白符、换行符之外的任意字符。你的任务是检测字符串中的圆括号是否配对,即“(”与“)”是否配对。如字符串“((a+b)* (c+d))”中是配对的,而“((a+b)*) c+d))”则不配对。

输入格式:

一个长度不超过100的非空字符串,该字符串中不会出现空格、换行符。

输出格式:

匹配及不匹配见样例。

输入样例一:

((a+b)*(c+d))

输出样例一:

parentheses match!

输入样例二:

((a+b)*)c+d))

输出样例二:

parentheses do not match!

参考答案:

#include<stdio.h>
#include<string.h>
int main(){
	char c[100];
	int a=0,len;
	
	scanf("%s",c);
	len=strlen(c);
	for(int i=0;i<len;i++){
		if(c[i]=='(') a++;
		if(c[i]==')') a--;
		if(a<0) {printf("parentheses do not match!");break;}
		
	}
	if(a==0) printf("parentheses match!");
	else if(a>0) printf("parentheses do not match!");
	
}

7-9 17进制 (100 分)

请写一段程序将17进制数转换为10进制。

输入格式:

为一个只包含小写字母的字符串(其中a代表17进制的0,b代表17进制的1,以此类推直到q代表17进制的16),字符串以’\n’结束。

输出格式:

是一个整数,转换后的10进制数。测试用例保证合法,且转换后的整数可以用int存储。

输入样例:

caa

输出样例:

578

参考答案:

#include<stdio.h>
#include<string.h>
int main()
{	int len,n=0;
	char c[100];
	gets(c);
	len=strlen(c);

	for(int i=0;i<len;i++){
			n=n*17+(c[i]-'a');
			
		} 
	printf("%d",n);
	return 0;
	}

2022版本更新

7-22 05_01_习题课一

某程要开习题课,由于教室座位有限,所以决定限制参加人数。于是规定:1、最多允许一半的班级里的同学参加;2、可以参加的班级最多允许一半的同学参加。现请你写一段程序来计算习题课最多可能有多少个学生参加。

输入格式:

为两行,第一行为一个整数n(0<n<100),代表班级的个数,第二行为n个正整数,分别代表每个班级的人数。

输出格式:

只有一行,为能够参加习题课的人数的最大值。(当数字为奇数时,一半指的是该数减一后除以2,测试用例保证所有整数可以用 int 类型存储)。

输入样例:

5
4 5 6 7 8

输出样例:

7

参考代码:

#include<bits/stdc++.h>
#include<string.h>
using namespace std;
int main(){
	int n,temp;
	int num,sum=0;
	int a[105]={0};
	
	cin>>n;
	for(int i=0;i<n;i++) cin>>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]){
				temp=a[j];
				a[j]=a[j+1];
				a[j+1]=temp;
			}
			}
	}
	
	num=n/2;
	for(int i=0;i<num;i++){
		sum+=a[i]/2;
	}
	
	cout<<sum<<endl;

}

7-23 05_02_最长连续上升子序列的长度

给定序列,请求出其最长连续上升子序列的长度。

注意:是连续上升子序列,不是最长上升子序列。

输入格式:

第一行为一个整数n(0<n<=1000),代表序列总长度。第二行为用空格分隔n个整数。测试用例保证所有整数可以用int类型存储。

输出格式:

只有一个整数,为给定序列最长连续上升子序列的长度。

输入样例:

15
1 1 2 3 4 5 6 7 3 3 5 5 3 3 9

输出样例:

7

参考代码:

#include<bits/stdc++.h>
#include<string.h>
using namespace std;
int main(){
	int n,temp;
	int a[1005]={0},b[1005]={1};
	
	cin>>n;
	for(int i=0;i<n;i++) {
		cin>>a[i];
		if(i>0&&a[i]>a[i-1]){
			b[i]=b[i-1]+1;
		}
		else b[i]=1;
	
	}
	
	for(int i=0;i<n-1;i++){
		for(int j=0;j<n-i-1;j++){
			if(b[j]<b[j+1]){
				temp=b[j];
				b[j]=b[j+1];
				b[j+1]=temp;
			}
			}
	}
	
	
	
	cout<<b[0]<<endl;

}

7-24 05_03_求极值

在一个nXn的二维整数数组中,每一行都有一个最小值,这n个最小值中有一个最大的。请写一段程序找出这个最大的最小值。

输入格式:

第一行为一个整数n,1<=n<=10,后边为n行,是nXn个整数(以空格分隔),即nXn的二维整数数组。

输出格式:

只有一行为三个整数,依次为这个最大的最小值及它所在行和列的下标(分别以一个空格分隔。如果某行的最小值出现多次,则要求记录列下标最小的那个,如果最大的最小值出现多次,则要求记录下标最小的那行)。测试数据保证所有整数均可以用int型存储。

输入样例:

3
1 2 3
4 5 6
7 8 9

 输出样例:

7 2 0

参考代码:

#include<bits/stdc++.h>
#include<string.h>
using namespace std;

int main(){
	int n;
	int a[15][15];
	int b[15];
	int temp[15];
	int temp1;
	int hang[15],lie[15];
	int result;
	
	
	cin>>n;
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++)
			cin>>a[i][j];
	}
	
	for(int i=0;i<n;i++){
		b[i]=a[i][0];
		temp[i]=b[i];
		hang[i]=i;
		lie[i]=0;
		for(int j=0;j<n;j++){
			if(a[i][j]<b[i]){
				b[i]=a[i][j];
				temp[i]=b[i];
				lie[i]=j;
			}
		}
	}
	
	for(int i=0;i<n-1;i++){
		for(int j=0;j<n-i-1;j++){
			if(temp[j]<temp[j+1]){
				temp1=temp[j];
				temp[j]=temp[j+1];
				temp[j+1]=temp1;
			}
		}
	}
	
	result=temp[0];
	for(int i=0;i<n;i++){
		if(result==b[i]){
			cout<<result<<" "<<i<<" "<<lie[i]<<endl;
			break;
		}
	}
}

 

 

7-37 07_05_单词统计

给定的字符串中只包含#和小写字母,其中#是分隔符,连续的小写字母构成单词。单词内部不会包含#号,也不存在两个单词之间没有#的情况。请你写一个程序来统计一下一行字符串中单词的数量和#的数量。

输入格式:

第一行为一个整数n(0<n<10),代表共有n个字符串。后边n行,每行一个长度不超过100的字符串。

测试用例保证输入合法。

输出格式:

共n行,每行依次对应输入各个字符串。

每行的格式如下:

首先是一个整数,代表单词的数量,跟着是一个空格;然后又是一个整数,代表#的数量,跟着又是一个空格;最后依次输出所有单词,单词之间用一个空格分隔,最后一个单词后边没有空格。如果单词的数量为0,则在应该输出单词的位置输出三个连续的#。

输入样例:

2
#
hello#world

输出样例:

0 1 ###
2 1 hello world

参考代码:

#include <stdio.h>
#include <string.h>
void Replace(char *a,char c)
{
    char *b;
    b = a;
    
    while (*a!='\0')
    {
        while(*b == c){b++;}
        
        if (*a == c)
        {
            
            *a = *b;
            *b = c;       
        }
        a++;
        b++;
        if(*b=='\0'){*a = '\0';}
    }
    
   
    return;
}

int main()
{
    char ip[50][500];
    int n,i,i1;
    int cw,ct,ctt;

    scanf("%d",&n);
    getchar();
    for (i=0;i<n;i++){gets(ip[i]);}

    for (i=0;i<n;i++)
    {
        cw=0;ct=0;
        for(i1=0;i1<strlen(ip[i]);i1++)
        {
            if ((ip[i][i1] == '#')&&(i1!=0))
            {
                if((ip[i][i1-1] == ' ')||(ip[i][i1-1] == '#'))
                {
                    ct++; 
                }
                
                else
                {
                    cw++;
                    ct++;
                    ip[i][i1] = ' ';
                }
            }
            if((ip[i][0] == '#')&&ct == 0)
            {
                ct++;
            }
        }
        
        
        
        Replace(&ip[i][0],'#');
        if((ip[i][strlen(ip[i])-1]!=' ')&&strlen(ip[i])>0)
                 cw++;
        else ip[i][strlen(ip[i])-1]='\0';

        if (cw!=0){
            printf("%d %d %s\n",cw,ct,ip[i]);
        }
        else printf("%d %d ###\n",cw,ct);


    }
    
}