acm第一周练习题


13/20
其他的做不出来

A - 查成绩

学生成绩查找系统是一个根据姓名查找学生成绩的系统。系统可以录入是学生的姓名和成绩,录完之后可以输入查找条件,即学生的姓名,查找该生的成绩,如果存在该生的信息,则输出该生成绩,否则给出查无此人的提示信息。
输入:题目输入包括录入学生信息和输入查找条件以及输入结束标志。insert语句表示录入学生信息,格式为字符insert+空格+字符串+空格+数字+换行符 ,例如 insert xiaohua 99 ,表示录入姓名为xiaohua的学生,其成绩为99 。 find语句表示查找某学生的信息,格式为字符find+空格+字符串+换行符。例如 find xiaohua。end语句表示输入结束,格式为字符end
输出:对应每一条find语句都应该有一条输出语句。对于find xiaohua这条输入语句,因为已经插入过xiaohua的成绩 需要输出 99+换行符,否则查找不到输出-1+换行符。
Sample Input
insert zhangsan 90
insert lisi 78
insert xiaoming 86
find xiaoming
find Jack
end
Sample Output
86
-1
因为第一道题能用python,所以用了

思路

f=[]
name=[]
s=[]
i=input().split()
while i[0]=='insert':
    name.append(i[1])
    s.append(i[2])
    i=input().split()
while i[0]=='find':
    f.append(i[1])
    i = input().split()
    if i=='end':
        break
for i in range(0,len(f)):
    q=0
    for j in range(0,len(name)):
        if f[i]==name[j]:
            print(s[j])
            q=1
            break
    if q==0:
        print("-1")

D - 回文数猜想

一个正整数,如果从左向右读(称之为正序数)和从右向左读(称之为倒序数)是一样的,这样的数就叫回文数。任取一个正整数,如果不是回文数,将该数与他的倒序数相加,若其和不是回文数,则重复上述步骤,一直到获得回文数为止。例如:68变成154(68+86),再变成605(154+451),最后变成1111(605+506),而1111是回文数。于是有数学家提出一个猜想:不论开始是什么正整数,在经过有限次正序数和倒序数相加的步骤后,都会得到一个回文数。至今为止还不知道这个猜想是对还是错。现在请你编程序验证之。
Input
每行一个正整数。
特别说明:输入的数据保证中间结果小于2^31。
Output
对应每个输入,输出两行,一行是变换的次数,一行是变换的过程。
Sample Input
27228
37649
Sample Output
3
27228—>109500—>115401—>219912
2
37649—>132322—>355553

思路

#include <stdio.h>
int researve(int n);
int main()
{
    int n,r;
    while(scanf("%d",&n)!=EOF)
    {
    r=n;
    int m=0,q=0;
    while(m=researve(n),m!= n)
    {           
       n=n+m;
       q++;
    }
    n=r;
    printf("%d\n",q);				//记录次数
    while(m=researve(n),m!= n)		//回文数即原数与翻转数相等
    {
       printf("%d--->",n);         
       n=n+m;                       //把n更新为 m + n;
    }
    printf("%d\n",n);
	}	
return 0;
}
    
int researve(int n) //翻转函数
{
    int t=0;
    while(n>0)
    {
        t=t*10+n%10;
        n=n/10;
    }
    return t;
}

F - 买鸡问题

百钱买百鸡问题:公鸡五文钱一只,母鸡三文钱一只,小鸡三只一文钱,用100文钱买100只鸡,公鸡母鸡、小鸡各买多少只?
本程序要求解的问题是:给定一个正整数n,用n文钱买n只鸡,问公鸡、母鸡、小鸡各买多少只?
输入格式
输入一个正整数n。
输出格式
如果有解,依次输出公鸡、母鸡、小鸡的个数(用正整数表示)。
如果无解,输出"No Answer."。
数据范围1<=n ≤200。
Sample Input
100
Sample Output
0 25 75
4 18 78
8 11 81
12 4 84

思路

解方程
x+y+z=n
5x+3y+1/3z=n

n=int(input())
x=-1
f=0
y=(n-(7*x))/4
while x<n:
    x=1+x
    y=(n-(7*x))//4
    z=n-x-y
    if x<0 or y<0 or z<0:
        continue
    if 7*x+4*y==n:
        print("%d %d %d" %(x,y,z))
        f=1
        continue
if f==0:
    print("No Answer.")

H - 最小新整数

给定一个十进制正整数n(0<n<1000000000),每个数位上数字均不为0。n的位数为m.现在从m位中删除k位(0<k<m),求生成的新整数最小为多少?
例如:n =9128456,k=2,则生成的新整数最小为12456。
输入格式
第一行t,表示有t组数据;
接下来t行,每一行表示一组测试数据,每组测试数据包含两个数字n, k。
输出格式
t行,每行一个数字,表示从n中删除k位后得到的最小整数。
Sample Input
2
9128456 2
1444 3
Sample Output
12456
1

思路

如果前面的数字大于后面的话就让所有的数字往前提一位

#include <stdio.h>
#include <string.h>
int main()
{
	char n[50];
	int t,b,len,flag=1;
	scanf("%d",&t);
	while(t--){
		scanf("%s %d",n,&b);
		len=strlen(n);
		for(int i=0;i<b;i++){
			for(int j=0;j<len-1;j++){
				if(n[j]>n[j+1]){
					for(int k=j;k<len-1;k++){
						n[k]=n[k+1];
					}
					break;
				}
			}
			len--;
		}
		for(int i=0;i<len;i++){
			printf("%c",n[i]);
		}
		printf("\n");
	}
}

I - 赶时间

花椰妹要去约会了!
因为花椰妹已经是老女人了,所以必然需要打扮一番,抹点粉啊,涂涂口红啦,画点眼影响啊…….许久过后花椰妹已然变成美女了!!
花椰妹看了下时间,已经不早了,可是桌面上还有好多好多瓶瓶罐罐没用,这怎么行!花椰妹现在想知道,她还有多少时间可以用于化妆?
输入格式
读入两个标准格式的时间,有小时,有分钟,有秒,格式如: h : m : s,即时:分:秒。
输出格式
输出这两个时间的差(秒为单位)。
数据范围
1<h<24,0 m<60,0<s<60。
所有的时间都是合法的,且上面的时间大于下面的时间。
Sample Input
11:10:10
10:30:30
Sample Output
2380

思路

%*c会跳过:

#include<stdio.h>
int main()
{
	int h1,m1,s1,h2,m2,s2,time;
	scanf("%d%*c%d%*c%d",&h1,&m1,&s1);
	scanf("%d%*c%d%*c%d",&h2,&m2,&s2);
	if (m1<m2)
	{
		m1+=60;
		h1-=1;
	}
	if (s1<s2)
	{
		s1+=60;
		m1-=1; 
	}
	h1-=h2;
	m1-=m2;
	s1-=s2;
	time=h1*3600+m1*60+s1;
	printf("%d",time);
	return 0;
}

J - 暖气坏了

蒜头君家的暖气经常出问题,每当暖气坏了,蒜头君就会持续感冒m天(从坏的那天算起,两次感冒时间重叠不会累加)。蒜头君去寻求预言家的帮助,预言家告诉他接下来n次暖气片坏掉的时间。根据这个时间,蒜头君就能知道他未来获得感冒的总天数。
输入格式
第一行两个整数n, m,表示暖气片坏掉的次数以及每次感冒的持续天数。
第二行n个整数ai,表示暖气片坏掉的日期。
数据范围:1<=n ≤10000,1 <=m, ai≤10^9,保证ai是严格递增的。
输出格式
一个整数,表示蒜头君感冒的总天数。
Sample Input
4 3
1 2 4 8
Sample Output
9

思路

看注释吧

#include<stdio.h>
int main()
{
	int n,m,i,s[10000],sum=0;
	scanf("%d %d",&n,&m);
	for (i=0;i<n;i++)
	{
		scanf("%d",&s[i]);
	}
	for (i=1;i<n;i++)
	{
		if (s[i]-s[i-1]<=m)	sum+=s[i]-s[i-1];//小于感冒天数一直感冒
		if (s[i]-s[i-1]>m)	sum+=m;//大于感冒天数只感冒m天
	}
	sum+=m;//最后一次暖气坏的时候感冒的天数
	printf("%d",sum);
}

K - 完美立方

在这里插入图片描述
Sample Input
24
Sample Output
Cube = 6, Triple = (3,4,5)
Cube = 12, Triple = (6,8,10)
Cube = 18, Triple = (2,12,16)
Cube = 18, Triple = (9,12,15)
Cube = 19, Triple = (3,10,18)
Cube = 20, Triple = (7,14,17)
Cube = 24, Triple = (12,16,20)

思路

没什么好说的,但注意abcd都大于一小于等于n,b<=c<=d,把我给坑了

#include<stdio.h>
int f(int a)
{
	return a*a*a;
}
int main()
{
	int a=6,b=3,c=4,d=5,n;
	scanf("%d",&n);
	while(a<=n)
	{
		if (f(a)==f(b)+f(c)+f(d)&&b<=c&&c<=d)
			printf("Cube = %d, Triple = (%d,%d,%d)\n",a,b,c,d);			
		d++;
		if (d>n){
			d=2;
			c++;
		}
		if (c>n){
			c=2;
			b++;
		}
		if (b>n){
			b=2;
			a++;
		}
	}
	return 0;
}

M - 母牛的故事

有一头母牛,它每年年中生一头小母牛。每头小母牛从第四个年头开始,每年年中 (才注意到)也生一头小母牛。请编程实现在第n年的时候(不算第n年出生的小母牛),共有多少头母牛?
输入格式
输入包括一个整数n(0<n<55)。
输出格式
输出在第n年的时候母牛的数量。
Sample Input 2
5
Sample Output 2
6

思路

在这里插入图片描述

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

思路2

#include<stdio.h>
int main(void)
{
	int f[55],i,n;
	while(scanf("%d",&n)!=EOF)
	{
		f[1]=1;f[2]=2;f[3]=3;
		for(i=4; i<=n;i++){
			f[i]=f[i-3]+f[i-1];
		}
		printf("%d\n",f[n]);
	}
	return 0;
}

N - 无限的路

甜甜从小就喜欢画图画,最近他买了一支智能画笔,由于刚刚接触,所以甜甜只会用它来画直线,于是他就在平面直角坐标系中画出如下的图形:
在这里插入图片描述
甜甜的好朋友蜜蜜发现上面的图还是有点规则的,于是他问甜甜:在你画的图中,我给你两个点,请你算一算连接两点的折线长度(即沿折线走的路线长度)吧。
Input
第一个数是正整数N(≤100)。代表数据的组数。
每组数据由四个非负整数组成x1,y1,x2,y2;所有的数都不会大于100。
Output
对于每组数据,输出两点(x1,y1),(x2,y2)之间的折线距离。注意输出结果精确到小数点后3位。
Sample Input
5
0 0 0 1
0 0 1 0
2 3 3 1
99 99 9 9
5 5 5 5
Sample Output
1.000
2.414
10.646
54985.047
0.000

思路

1.这个老是过不去,不知道为什么
在这里插入图片描述

#include<stdio.h>
#include<math.h>
double f(double n)
{
	return sqrt((n*n)+(n+1)*(n+1));
}
int main()
{
	int y1,x2,y2,n,t;
	scanf("%d",&n);
	double x1,s;
	while(n--)
	{
	scanf("%lf %d %d %d",&x1,&y1,&x2,&y2);
	s=0;
		if (x1+y1>x2+y2)	
		{
			t=x2;x2=x1;x1=t;
			t=y2;y2=y1;y1=t;			
		}
		if (x1+y1<x2+y2)	s+=(x2+y1)*sqrt(2);
		
		if (x1+y1==0)
		{
			s+=1;
			x1=0;y1=1;	
		}
		if (x1+y1==x2+y2)
		{
			printf("%.3lf\n",s);
			continue;
		}	
		x1=x1+y1;y1=0;
		y2=x2+y2;x2=0;		
		while (x1+y1!=x2+y2)
		{
			if (x1==0)
			{
				s+=y1*sqrt(2);
				x1=y1;
				y1=0;
				
			}
			if (y1==0)
			{
				s+=f(x1);
				y1=x1+1;
				x1=0;
			}
		}
	printf("%.3lf\n",s);
}
	return 0;
}

思路2

#include <stdio.h>
#include <stdlib.h>
#include<math.h>
int main()
{
    int i,x1,x2,y1,y2,s;
    double m,n,f[1000];
    scanf("%d",&s);
    f[0]=0;f[1]=1;
    for(i=2;i<=200;i++)
    {
        f[i]=f[i-1]+sqrt(2*(i-1)*(i-1))+sqrt(i*i+(i-1)*(i-1));
    }
    while(s--)
    {
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        m=f[x1+y1]+sqrt(2*x1*x1);
        n=f[x2+y2]+sqrt(2*x2*x2);
        printf("%.3lf\n",fabs(m-n));
    }
    return 0;
}

O - 统计元音

统计每个元音字母在字符串中出现的次数。
Input
输入数据首先包括一个整数n,表示测试实例的个数,然后是n行长度不超过100的字符串。
Output
对于每个测试实例输出5行,格式如下:
a:num1
e:num2
i:num3
o:num4
u:num5
多个测试实例之间由一个空行隔开。 这里划重点每次打印都要换两行,最后一个换一行

请特别注意:最后一块输出后面没有空行:)
Sample Input
2
aeiou
my name is ignatius
Sample Output
a:1
e:1
i:1
o:1
u:1

a:2
e:1
i:3
o:0
u:1

思路

#include<string.h>
int main()
{
	char s[1000];
	int n;
	scanf("%d",&n);
	getchar();
	int a1[n],e1[n],i1[n],o1[n],u1[n];
	while(n--)
	{
		int a=0,e=0,i=0,o=0,u=0;
		gets(s);
		int t,len;
		len=strlen(s);
		for(t=0;t<len;t++)
		{
			if (s[t]=='a')
				a++;
			if (s[t]=='e')
				e++;
			if (s[t]=='i')
				i++;
			if (s[t]=='o')
				o++;
			if (s[t]=='u')
				u++;
		}
		printf("a:%d\ne:%d\ni:%d\no:%d\nu:%d",a,e,i,o,u);
		if (n!=0) printf("\n\n");
		else printf("\n");
	}
	return 0;
}

P - 求数列的和

数列的定义如下:
数列的第一项为n,以后各项为前一项的平方根,求数列的前m项的和。
Input
输入数据有多组,每组占一行,由两个整数n(n<10000)和m(m<1000)组成,n和m的含义如前所述。
Output
对于每组输入数据,输出该数列的和,每个测试实例占一行,要求精度保留2位小数。
Sample Input
81 4
2 2
Sample Output
94.73
3.41

思路

#include<stdio.h>
#include<math.h>
double array(int n,int m)
{
	double k=n,i,sum;     
        sum=k;                  
	for(i=2;i<=m;i++)
	{
		k=sqrt(k);
		sum+=k;
	}
	return sum;	
}
int main()
{
	int m,n;
	while(scanf("%d%d",&n,&m)!= EOF) 
	{
		printf("%.2lf\n",array(n,m));
 	}
return 0;
}

思路2

#include <stdio.h>
#include <math.h>
int main(void)
{
    int n, m;
    double sum, a;
    while(scanf("%d%d", &n, &m) != EOF) 
	{
        sum = n;
        a = n;
        while(--m) {		
            a = sqrt(a);
            sum += a;
        }
    	printf("%.2f\n", sum);
    }
return 0;
}

Q - 数字游戏

小K同学向小Р同学发送了一个长度为8的o1字符串来玩数字游戏,小Р同学想要知道字符串中究竟有多少个1
注意:01字符串为每一个字符是0或者1的字符串,如“101”(不含双引号)为一个长度为3的01字符串。
输入格式
输入只有一行,一个长度为8的01字符串s。
输出格式
输出只有一行,包含一个整数,即o1字符串中字符1的个数。
数据范围
对于20%的数据,保证输入的字符全部为0。
对于100%的数据,输入只可能包含字符0和字符1,字符串长度固定为8。
Sample Input
00010100
Sample Output
2
Sample Explain
该 01 字符串中有 2个字符1。

思路

#include<stdio.h>
int main()
{
	char s[9];
	gets(s);
	int a=0;
	for (int i=0;i<8;i++)
	{
		if (s[i]=='1')	a++;
	}
	printf("%d",a);
	return 0;
}

R - 轻重搭配

n个同学去动物园参观,原本每人都需要买一张门票,但售票处推出了一个优惠活动,一个体重为x的人可以和体重至少为2x配对,这样两人只需买一张票。现在给出了n个人的体重,请你计算他们最少需要买几张门票?
输入格式
第一行一个整数n,表示人数。
第二行n个整数,每个整数a表示每个人的体重。
输出格式
一个整数,表示最少需要购买的门票数目。
数据范围
对于30%的数据:1<n<25,1≤a ≤100。
对于60%的数据:1<n≤10000,1≤a≤1000。
对于100%的数据:1<n≤5.105,1≤a≤105。
样例解释
1和9配对,7和3配对,剩下5,5单独,一共买四张票。
Sample Input
6
1 9 7 3 5 5
Sample Output
4

思路

首先按顺序排列,然后将其分为两半,将a[0] 与a[3],a[4],a[5]一个一个比大小,若a[3]小则++直到全比完,当遇到合适的则停止加让票en-1同时让下一个a[1]试.

int main()
{
	int n,a[500000],i=0,ct,en;
	scanf("%d",&n);
	for(;i<n;i++) scanf("%d",&a[i]);
	Sort(a,n-1,0,n-1);
	ct=n/2;en=n;
	for(i=0;i<n/2;i++)
	{
		while(2*a[i]>a[ct]&&ct<n) ct++;
		if (ct>=n) break;
		en--;
		ct++;
	}
	printf("%d\n",en);
} 

那个sort本来想用冒泡的然后Time Limit
所以用了快排

void swap(int *a, int *b)    
{  
    int temp;  
    temp = *a;  
    *a = *b;  
    *b = temp;  
}  
void Sort(int *arr, int maxlen, int begin, int end)  
{  
    int i, j;  
    if (begin < end) {  
        i = begin + 1;  
        j = end;        
        while (i < j) {  
            if(arr[i] > arr[begin]) {  
                swap(&arr[i], &arr[j]); 
                j--;  
            } else {  
                i++; 
            }  
        }  
        if (arr[i] >= arr[begin]) {  
            i--;  
        }  
        swap(&arr[begin], &arr[i]);      
        Sort(arr, maxlen, begin, i);  
        Sort(arr, maxlen, j, end);  
    }  
} 

以下是没做出来的题

B - 放暑假

在这里插入图片描述

C - 展开字符串

在这里插入图片描述

E - 宇航员

问题描述:
  宇航员在太空中迷失了方向,在他的起始位置现在建立一个虚拟xyz坐标系,称为绝对坐标系,宇航员正面的方向为x轴正方向,头顶方向为z轴正方向,则宇航员的初始状态如下图所示:
  在这里插入图片描述
现对六个方向分别标号,x,y,z正方向分别为0,1,2,负方向分别为3,4,5;称它们为绝对方向。宇航员在宇宙中只沿着与绝对坐标系xyz轴平行的方向行走,但是他不知道自己当前绝对坐标和自己面向的绝对方向。

任务描述:
  请根据宇航员对自己在相对方向上移动的描述确定宇航员最终的绝对坐标和面向的绝对方向。对在相对方向上移动的描述及意义如下:
forward x  向前走x米。
back x 先转向后,再走x米。
left x 先转向左,再走x米。
right x 先转向右,再走x米。
up x 先面向上,再走x米。
down x 先面向下,再走x米。
其中向上和向下如下图所示:
在这里插入图片描述
Input
第一行一个正整数m,表示测试数据的组数。每组测试数据第一行是一个正整数n(1<=n<=10000)表示宇航员行走的次数,下面n行每行输入一次相对行走,格式如上所述,其中( 1 <= x <= 10000 为正整数)。
Output
对于每组输入数据输出一行,x y z p, 中间用空格隔开,x y z是宇航员的位置的绝对坐标,p是宇航员面向的绝对方向编号(0<=p <=5)。
Sample Input
1
6
left 10
right 11
up 12
down 13
forward 14
back 15
Sample Output
23 -10 12 3

G - 水贴

在这里插入图片描述
Sample Input
5 3 5
4 5 3 4 3
2 4 5
Sample Output
8

思路

在这里插入图片描述

L - N对数的排列问题

在这里插入图片描述

S - Powered Addition

图图学长最近特别喜欢整整齐齐的数组。他现在有一个长度为 n 的数组 a ,因为图图学长很忙,所以请你帮帮他。第 x 秒内你可以对数组执行以下操作:

选择介于 1 和 n 之间的索引 i1 , i2 , … , ik , 然后在数组 a 对应位置加上 2x-1 . 注意:第 x 秒你可以不选择任何索引.
找出最小的时间 T 让数组 a 不递减.

当a1 <= a2 <= … <= an 时数组 a 是不递减的.

你需要解决 t 个独立的测试用例。

Input
第一行是一个整数 t (1 <= t <= 104) — 测试样例的数量.

每个测试用例的第一行包含单个整数 n (1 <= n <= 105) — 数组 a 的长度. 保证输入的所有测试用例中 n 值的和不超过 105

每个测试用例的第二行包含 n 个整数 a1, a2,…, an (-109 <= ai <= 109)

Output
对于每个测试用例,打印可以使数组 a 变得非递减的最短时间。

Example
Input

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

Output

2
0
3

Note
在第一个测试用例中,如果在第 1 秒选择索引 3, 4 然后在第 2 秒选择索引 4 , 数组 a 将变成 [1, 7, 7, 8]. 可能有其他方式让数组 a 在 2 秒内变得非递减,但是 2 秒是最短的时间.
在第二个测试用例中, a 已经非递减,所以答案是 0.
在第三个测试用例中 如果在前 2 秒什么都不做,在第 3 秒选择索引 2 ,数组 a 将变成 [0, 0].

T - Puzzle From the Future

在这里插入图片描述
Example
Input
5
1
0
3
011
3
110
6
111000
6
001011
Output
1
110
100
101101
101110
在这里插入图片描述

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值