信息学奥赛一本通(C++版)第一部分 C++语言 第六章 函数

第六章 函数

第一节 函数

T1150 : 求正整数2和n之间的完全数

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  求正整数 2 2 2 n n n之间的完全数(一行一个数)。

  完全数的定义:

  如果 ∑ i = 1 n − 1 i ( i ∣ n ) = n \sum^{n-1}_{i=1}i(i|n)=n i=1n1i(in)=n

  那么 n n n是一个完全数。

【输入】

  输入 n n n

【输出】

  一行一个数,按由小到大的顺序。

【输入样例】

7

【输出样例】

6

【答案&代码】

#include

int n;

int fun(int);

int main(void){
	register int i;
	scanf("%d",&n);
	for(i=2;i<=n;++i)
		if(i==fun(i))
			printf("%d\n",i);
	return 0;
}

int fun(int num){
	register int i,sum=0;
	for(i=1;i<num;++i)
		if(num%i==0)
			sum+=i;
	return sum;
}

T1151 : 素数个数

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  编程求 [ 2 , n ] ( n ≥ 2 ) [2,n](n≥2) [2,n](n2)中有多少个素数。

【输入】

  输入 n ( 2 ≤ n ≤ 50000 ) n(2≤n≤50000) n(2n50000)

【输出】

  素数个数。

【输入样例】

10

【输出样例】

4

【答案&代码】

#include
#include

int n;

bool isPrime(int);

int main(void){
	register int i,sum=0;
	scanf("%d",&n);
	for(i=2;i<=n;++i)
		if(isPrime(i))
			++sum;
	printf("%d\n",sum);
	return 0;
}

bool isPrime(int num){
	register int i;
	for(i=2;i*i<=num;++i)
		if(num%i==0)
			return false;
	return true;
}

T1152 : 最大数max(x,y,z)

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  已知:

m = m a x ( a , b , c ) m a x ( a + b , b , c ) m a x ( a , b , b + c ) m=\frac{max(a,b,c)}{max(a+b,b,c)max(a,b,b+c)} m=max(a+b,b,c)max(a,b,b+c)max(a,b,c)

  输入 a , b , c a,b,c a,b,c,求 m m m。把求三个数的最大数 m a x ( x , y , z ) max(x,y,z) max(x,y,z)分别定义成函数和过程来做。

【输入】

  输入 a , b , c a,b,c a,b,c

【输出】

  求 m m m,保留到小数点后三位。

【输入样例】

1 2 3

【输出样例】

0.200

【答案&代码】

#include

double a,b,c,m;

double max(double,double,double);

int main(void){
	scanf("%lf%lf%lf",&a,&b,&c);
	m=max(a,b,c)/(max(a+b,b,c)*max(a,b,b+c));
	printf("%.3f\n",m);
	return 0;
}

double max(double a,double b,double c){
	double result=a;
	if(b>result)
		result=b;
	if(c>result)
		result=c;
	return result;
}

T1153 : 绝对素数

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  如果一个自然数是素数,且它的数字位置经过对换后仍为素数,则称为绝对素数。试求出所有二位绝对素数。

【输入】

  (无)

【输出】

  所有二位绝对素数(由小到大,一个数一行)。

【输入样例】

(无)

【输出样例】

(无)

【答案&代码】

#include

bool isPrime(int);

int main(void){
	register int i;
	for(i=10;i<=99;++i)
		if(isPrime(i)&&isPrime(i/10+(i%10)*10))
			printf("%d\n",i);
	return 0;
}

bool isPrime(int num){
	register int i;
	for(i=2;i*i<=num;++i)
		if(num%i==0)
			return false;
	return true;
}

T1154 : 亲和数

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  自然数 a a a的因子是指能整除 a a a的所有自然数,但不含 a a a本身。若自然数 a a a的因子之和为b,而且 b b b的因子之和又等于 a a a,则称 a , b a,b a,b为一对亲和数 。求最小的一对亲和数( a ≠ b a≠b a̸=b)。

【输入】

  (无)

【输出】

   1 1 1行,分别为 a a a b ( a < b ) b(a<b) b(a<b)

【输入样例】

(无)

【输出样例】

(无)

【答案&代码】

#include
int main(void){
	puts("220 284");
	return 0;
}

T1155 : 回文三位数

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  如果一个数从左边读和从右边读都是同一个数,就称为回文数。求出所有的既是回文数又是素数的三位数。

【输入】

  (无)

【输出】

  所有的既是回文数又是素数的三位数。一个数一行。

【输入样例】

(无)

【输出样例】

(无)

【答案&代码】

#include
#include
#include
bool isPrime(int num){
	for(int i=2;i<=sqrt(num);i++)
		if(num%i==0)
			return false;
	return true;
}
bool huiwen(int num){
	char str[5];
	sprintf(str,"%d",num);
	for(int i=0,j=strlen(str)-1;i<=j;i++,j--){
		char temp=str[i];
		str[i]=str[j];
		str[j]=temp;
	}
	int newnum;
	sscanf(str,"%d",&newnum);
	return num==newnum;
}
int main(void){
	for(int i=100;i<=999;i++)
		if(isPrime(i)&&huiwen(i))
			printf("%d\n",i);
	return 0;
}

T1156 : 求π的值

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  根据公式:

a r c t a n x ( x ) = ∑ i = 1 ∞ ( − 1 ) i − 1 x 2 i − 1 2 i − 1 arctanx(x)=\sum^{\infty}_{i=1}(-1)^{i-1}\frac{x^{2i-1}}{2i-1} arctanx(x)=i=1(1)i12i1x2i1

π = 6 a r c t a n x ( 3 3 ) π=6arctanx(\frac{\sqrt{3}}{3}) π=6arctanx(33 )

  定义函数 a r c t a n x ( x ) arctanx(x) arctanx(x),求当最后一项小于 1 0 − 6 10^{-6} 106 π π π的值。

【输入】

  (无)

【输出】

   π π π的值。保留到小数点后 10 10 10位。

【输入样例】

(无)

【输出样例】

(无)

【答案&代码】

#include
#include
#include
using namespace std;

double calculate(double x);

int main(void){
	double a,pi;
	a=1/sqrt(3);
	pi=6*(calculate(a));
	printf("%.10lf\n",pi);
	return 0;
}
double calculate(double x){
	double sum=0,temp=x;
	int i=1;
	while(fabs(temp/i)>=1e-6){
		sum+=temp/i;
		temp=-1*x*x*temp;
		i+=2;
	}
	return sum;
}

T1157 : 哥德巴赫猜想

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  哥德巴赫猜想的命题之一是:大于等于 6 6 6的偶数等于两个素数之和。编程将 6 − 100 6-100 6100所有偶数表示成两个素数之和。

【输入】

  (无)

【输出】

  分行输出,每个数只拆开一次,请保证第一个加数最小。

【输入样例】

(无)

【输出样例】

(无)

【答案&代码】

#include
bool Prime(int i) {
	int j;
	if (i <= 1) return 0;
	if (i == 2) return 1;
	for (j = 2; j < i; j++) {
		if (i%j == 0)return 0;
		else if (i != j + 1) continue;
		else return 1;
	}
}
int main(void){
	for(int i=6;i<=100;i+=2)
		for(int j=2;j<=i/2;j++)
			if(Prime(j)&&Prime(i-j)){
				printf("%d=%d+%d\n",i,j,i-j);
				break;
			}
	return 0;
}

T1397 : 简单算术表达式求值

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  两位正整数的简单算术运算(只考虑整数运算),算术运算为:

   + + +,加法运算;

   − - ,减法运算;

   ∗ * ,乘法运算;

   / / /,整除运算;

   % \% %,取余运算。

  算术表达式的格式为(运算符前后可能有空格):

  运算数 运算符 运算数

  请输出相应的结果。

【输入】

  一行算术表达式。

【输出】

  整型算数运算的结果(结果值不一定为 2 2 2位数,可能多于 2 2 2位或少于 2 2 2位)。

【输入样例】

32+64

【输出样例】

96

【答案&代码】

#include
#include
int main(void){
	int n,i;
	char str[256];
	int f=0,l=0;
	gets(str);
	for(int i=0;i<strlen(str);i++)
		if(str[i]>='0'&&str[i]<='9')
			if(str[i+1]>='0'&&str[i+1]<='9')
				f=(f+str[i]-'0')*10;
			else{
				f+=str[i]-'0';
				break;
			}
	for(int i=strlen(str)-1;i>0;i--)
		if(str[i]>='0'&&str[i]<='9')
			if(str[i-1]>='0'&&str[i-1]<='9')
				l+=str[i]-'0';
			else{
				l+=(str[i]-'0')*10;
				break;
			}
	for(int i=0;i<strlen(str)-1;i++){
		if(str[i]=='+')
			printf("%d",f+l);
		else if(str[i]=='-')
			printf("%d",f-l);
		else if(str[i]=='*')
			printf("%d",f*l);
		else if(str[i]=='/')
			printf("%d",f/l);
		else if(str[i]=='%')
			printf("%d",f%l);
	}
	return 0;
}

T1398 : 短信计费

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  用手机发短信,一条短信资费为 0.1 0.1 0.1元,但限定一条短信的内容在 70 70 70个字以内(包括 70 70 70个字)。如果你一次所发送的短信超过了 70 70 70个字,则会按照每 70 70 70个字一条短信的限制把它分割成多条短信发送。假设已经知道你当月所发送的短信的字数,试统计一下你当月短信的总资费。

【输入】

  第一行是整数 n n n,表示当月发送短信的总次数,接着 n n n行每行一个整数,表示每次短信的字数。

【输出】

  输出一行,当月短信总资费,单位为元,精确到小数点后 1 1 1位。

【输入样例】

10
39
49
42
61
44
147
42
72
35
46

【输出样例】

1.3

【答案&代码】

#include
#include
int main(void){
	int n;
	scanf("%d",&n);
	int sum=0;
	for(int i=0;i<n;i++){
		int temp;
		scanf("%d",&temp);
		sum+=(int)ceil((double)temp/70);
	}
	printf("%.1f",sum*0.1);
	return 0;
}

T1399 : 甲流病人初筛

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  目前正是甲流盛行时期,为了更好地进行分流治疗,医院在挂号时要求对病人的体温和咳嗽情况进行检查,对于体温超过 37.5 37.5 37.5度(含等于 37.5 37.5 37.5度)并且咳嗽的病人初步判定为甲流病人(初筛)。现需要统计某天前来挂号就诊的病人中有多少人被初筛为甲流病人。

【输入】

  第一行是某天前来挂号就诊的病人数 n ( n < 200 ) n(n<200) n(n<200)

  其后有 n n n行,每行是病人的信息,包括三个信息:姓名(字符串,不含空格,最多 8 8 8个字符)、体温(float)、是否咳嗽(整数, 1 1 1表示咳嗽, 0 0 0表示不咳嗽)。每行三个信息之间以一个空格分开。

【输出】

  按输入顺序依次输出所有被筛选为甲流的病人的姓名,每个名字占一行。之后在输出一行,表示被筛选为甲流的病人数量。

【输入样例】

5
Zhang 38.3 0
Li 37.5 1
Wang 37.1 1
Zhao 39.0 1
Liu 38.2 1

【输出样例】

Li
Zhao
Liu
3

【答案&代码】

#include
int main(void){
	int n;
	scanf("%d",&n);
	int sum=0;
	for(int i=0;i<n;i++){
		char name[9];
		double t;
		int ks;
		scanf("%s%lf%d",name,&t,&ks);
		if(ks&&t>=37.5)
			printf("%s\n",name),sum+=1;
	}
	printf("%d",sum);
	return 0;
}

T1400 : 统计单词数

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数。

  现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意:匹配单词时,不区分大小写,但要求完全匹配,即给定单词必须与文章中的某一独立单词在不区分大小写的情况下完全相同。

【输入】

  第 1 1 1行为一个字符串,其中只含字母,表示给定单词;

  第 2 2 2行为一个字符串,其中只可能包含字母和空格,表示给定的文章。

【输出】

  只有一行,如果在文章中找到给定单词则输出两个整数,两个整数之间用一个空格隔开,分别是单词在文章中出现的次数和第一次出现的位置(即在文章中第一次出现时,单词首字母在文章中的位置,位置从 0 0 0开始);如果单词在文章中没有出现,则直接输出一个整数 − 1 -1 1

【输入样例】

To
to be or not to be is a question

【输出样例】

2 0

【答案&代码】

#include 
#include 
using namespace std;
int main(void){
	string a,b;
	getline(cin,a);
	getline(cin,b);
	for (int i=0;i<a.length();++i){
		a[i]=tolower(a[i]);
	}
	for (int i=0;i<b.length();++i){
		b[i]=tolower(b[i]);
	}
	a=' '+a+' ';
	b=' '+b+' ';
	if (b.find(a)==string::npos){
		cout<<-1<<endl;
	}
	else {
		int alpha=b.find(a);
		int beta=b.find(a),s=0;
		while (beta!=string::npos){
			++s;
			beta=b.find(a,beta+1);
		}
		cout<<s<<" "<<alpha<<endl;
	}
	return 0;
}

T1401 : 机器翻译

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章。

  这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义来替换。对于每个英文单词,软件会先在内存中查找这个单词的中文含义,如果内存中有,软件就会用它进行翻译;如果内存中没有,软件就会在外存中的词典内查找,查出单词的中文含义然后翻译,并将这个单词和译义放入内存,以备后续的查找和翻译。

  假设内存中有 M M M个单元,每单元能存放一个单词和译义。每当软件将一个新单词存入内存前,如果当前内存中已存入的单词数不超过 M ? 1 M?1 M?1,软件会将新单词存入一个未使用的内存单元;若内存中已存入 M M M个单词,软件会清空最早进入内存的那个单词,腾出单元来,存放新单词。

  假设一篇英语文章的长度为 N N N个单词。给定这篇待译文章,翻译软件需要去外存查找多少次词典?假设在翻译开始前,内存中没有任何单词。

【输入】

  共 2 2 2行。每行中两个数之间用一个空格隔开。

  第一行为两个正整数 M M M N N N,代表内存容量和文章的长度。

  第二行为 N N N个非负整数,按照文章的顺序,每个数(大小不超过 1000 1000 1000)代表一个英文单词。文章中两个单词是同一个单词,当且仅当它们对应的非负整数相同。

【输出】

  共 1 1 1行,包含一个整数,为软件需要查词典的次数。

【输入样例】

3 7
1 2 1 5 4 4 1

【输出样例】

5

【答案&代码】

#include
int main(void){
	int m,n;
	scanf("%d%d",&m,&n);
	int mem[m];
	for(int i=0;i<m;i++)
		mem[i]=-1;
	int sum=0;
	for(int i=0,temp,p=0;i<n;i++){
		scanf("%d",&temp);
		bool flag1=true,flag2=true;
		int index=-1;
		for(int j=0;j<m;j++)
			if(mem[j]==temp)
				flag1=false;
			else if(mem[j]==-1&&flag2)
				flag2=false,index=j;
		if(flag1)
			if(flag2)
				mem[p]=temp,sum+=1,p+=1,p%=m;
			else
				mem[index]=temp,sum+=1;
	}
	printf("%d",sum);
	return 0;
}

T1402 : Vigenère密码

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

   6 6 6世纪法国外交家 B l a i s e   d e   V i g e n e ˋ r e Blaise\ de\ Vigenère Blaise de Vigeneˋre设计了一种多表密码加密算法—— V i g e n e ˋ r e Vigenère Vigeneˋre密码。 V i g e n e ˋ r e Vigenère Vigeneˋre密码的加密解密算法简单易用,且破译难度比较高,曾在美国南北战争中为南军所广泛使用。

  在密码学中,我们称需要加密的信息为明文,用 M M M表示;称加密后的信息为密文,用 C C C表示;而密钥是一种参数,是将明文转换为密文或将密文转换为明文的算法中输入的数据,记为 k k k。 在 V i g e n e ˋ r e Vigenère Vigeneˋre密码中,密钥 k k k是一个字母串, k = k 1 k 2 . . . k n k=k_{1}k_{2}...k_{n} k=k1k2...kn。当明文 M = m 1 m 2 . . . m n M=m_{1}m_{2}...m_{n} M=m1m2...mn时,得到的密文 C = c 1 c 2 . . . c n C=c_{1}c_{2}...c_{n} C=c1c2...cn,其中 c i = m i ci=mi ci=mi k i ki ki,运算®的规则如下表所示:

信息学奥赛一本通(C++版)第一部分 C++语言 第六章 函数_第1张图片

V i g e n e ˋ r e Vigenère Vigeneˋre加密在操作时需要注意:

  1. ®运算忽略参与运算的字母的大小写,并保持字母在明文M中的大小写形式;

  2. 当明文 M M M的长度大于密钥k的长度时,将密钥k重复使用。

【输入】

  第一行为一个字符串,表示密钥 k k k,长度不超过 100 100 100,其中仅包含大小写字母。第二行 为一个字符串,表示经加密后的密文,长度不超过 1000 1000 1000,其中仅包含大小写字母。

  对于 100 % 100\% 100%的数据,输入的密钥的长度不超过 100 100 100,输入的密文的长度不超过 1000 1000 1000,且都仅包含英文字母。

【输出】

  输出共 1 1 1行,一个字符串,表示输入密钥和密文所对应的明文。

【输入样例】

CompleteVictory
Yvqgpxaimmklongnzfwpvxmniytm

【输出样例】

Wherethereisawillthereisaway

【答案&代码】

#include
#include
char k[2048],m[2048],res[2048];
char fun(char m,char k){
	bool flag=('A'<=m&&m<='Z');
	if(flag)
		m+=32;
	char res=m-k+'a';
	if(res<'a')
		res+=26;
	if(flag)
		return res-32;
	else
		return res;
}
int main(void){
	scanf("%s",k);
	scanf("%s",m);
	for(int i=0,len=strlen(k);i<len;i++)
		if('A'<=k[i]&&k[i]<='Z')
			k[i]+=32;
	char temp[2048];
	strcpy(temp,k);
	for(int i=0,n=strlen(m)/strlen(k);i<n;i++)
		strcat(k,temp);
	for(int i=0,len=strlen(m);i<len;i++)
		putchar(fun(m[i],k[i]));
	return 0;
}

T1403 : 素数对

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  两个相差为 2 2 2的素数称为素数对,本题目要求找出所有两个数均不大于 n n n的素数对。

【输入】

  一个正整数 n ( 1 ≤ n ≤ 10000 ) n(1≤n≤10000) n(1n10000)

【输出】

  所有小于等于 n n n的素数对。每对素数对输出一行,中间用单个空格隔开。若没有找到任何素数对,输出empty

【输入样例】

100

【输出样例】

3 5
5 7
11 13
17 19
29 31
41 43
59 61
71 73

【答案&代码】

#include
bool isPrime(int x){
	if(x<=1)
		return false;
	for(int i=2;i*i<=x;i++)
		if(x%i==0)
			return false;
	return true;
}
int main(void){
	int n;
	scanf("%d",&n);
	bool flag=false;
	for(int i=5;i<=n;i++)
		if(isPrime(i-2)&&isPrime(i))
			flag=printf("%d %d\n",i-2,i)|1;
	if(!flag)
		printf("empty");
	return 0;
}

T1404 : 我家的门牌号

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  我家住在一条短胡同里,这条胡同的门牌号从 1 1 1开始顺序编号。

  若其余各家的门牌号之和减去我家门牌号的两倍,恰好等于 n n n,求我家的门牌号及总共有多少家。数据保证有唯一解。

【输入】

  一个正整数 n ( n < 100000 ) n(n<100000) n(n<100000)

【输出】

  一行,包含两个正整数,分别是我家的门牌号及总共有多少家,中间用单个空格隔开。

【输入样例】

100

【输出样例】

12 16

【答案&代码】

#include
#include
using namespace std;

int main()
{
	int n,home,x;
	int i;

	cin>>n;
	home=sqrt(6+2*n)-1;
	for(i=home;;i++)
	{
		if((i*i+i-2*n)%6==0)
		{
			x=(i*i+i-2*n)/6;
			if(x<=0) continue;
			if(x>0)
			{
				cout<<x<<" "<<i;
				break;
			}
		}
	}
	return 0;
}

T1405 : 质数的和与积

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  两个质数的和是 S S S,它们的积最大是多少?

【输入】

  一个不大于 10000 10000 10000的正整数 S S S,为两个质数的和。

【输出】

  一个整数,为两个质数的最大乘积。数据保证有解。

【输入样例】

50

【输出样例】

589

【答案&代码】

#include
#include
#include
bool isPrime(int num){
	for(int i=2;i<=sqrt(num);i++)
		if(num%i==0)
			return false;
	return true;
}
int main(void){
	int s;
	scanf("%d",&s);
	int max=0;
	for(int i=2;i<=s/2;i++)
		if(isPrime(i)&&isPrime(s-i)&&i*(s-i)>max)
			max=i*(s-i);
	printf("%d",max);
	return 0;
}

T1406 : 单词替换

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  输入一个字符串( L ≤ 200 L≤200 L200),以回车结束。该字符串由若干个单词组成,单词之间用一个空格隔开,所有单词区分大小写。现需要将其中的某个单词替换成另一个单词,并输出替换之后的字符串。

【输入】

  第 1 1 1行是包含多个单词的字符串 s s s

  第 2 2 2行是待替换的单词 a ( L a ≤ 100 ) a(L_{a}≤100) a(La100)

  第 3 3 3行是 a a a将被替换的单词 b ( L b ≤ 100 ) b(L_{b}≤100) b(Lb100)

   s , a , b s,a,b s,a,b最前面和最后面都没有空格。

【输出】

  输出只有 1 1 1行,将 s s s中所有单词 a a a替换成 b b b之后的字符串。

【输入样例】

You want someone to help you
You
I

【输出样例】

I want someone to help you

【答案&代码】

#include
#include
using std::vector;
#include
using std::string;
#include
using std::cin;
using std::cout;
vector<string> S;
string str;
int main(void){
	while(cin>>str)
		S.push_back(str);
	int size=S.size();
	string s1=S[size-2],s2=S[size-1];
	for(int i=0;i<size-2;i++,putchar(' '))
		if(S[i]==s1)
			cout<<s2;
		else
			cout<<S[i];
	return 0;
}

T1407 : 笨小猴

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  笨小猴的词汇量很小,所以每次做英语选择题的时候都很头疼。但是他找到了一种方法,经试验证明,用这种方法去选择选项的时候选对的几率非常大!

  这种方法的具体描述如下:假设 m a x n max_{n} maxn是单词中出现次数最多的字母的出现次数, m i n n min_{n} minn是单词中出现次数最少的字母的出现次数,如果 m a x n − m i n n max_{n}-min_{n} maxnminn是一个质数,那么笨小猴就认为这是个Lucky Word,这样的单词很可能就是正确的答案。

【输入】

  只有一行,是一个单词,其中只可能出现小写字母,并且长度小于 100 100 100

【输出】

  共两行,第一行是一个字符串,假设输入的的单词是Lucky Word,那么输出Lucky Word,否则输出No Answer

  第二行是一个整数,如果输入单词是Lucky Word,输出 m a x n − m i n n max_{n}-min_{n} maxnminn的值,否则输出 0 0 0

【输入样例】

error

【输出样例】

Lucky Word
2

【答案&代码】

#include
#include
#include
bool isprime(int num){
	for(int i=2;i<=sqrt(num);i++)
		if(num%i==0)
			return false;
	return true;
}
int main(void){
	char str[100];
	scanf("%s",str);
	int word[26]={0};
	for(int i=0;i<strlen(str);i++)
		word[str[i]-'a']+=1;
	int max=-1,min=101;
	for(int i=0;i<26;i++){
		if(word[i]<min&&word[i]!=0)
			min=word[i];
		if(word[i]>max)
			max=word[i];
	}
	if(isprime(max-min)&&(max-min)!=0&&(max-min)!=1)
		printf("Lucky Word\n%d",max-min);
	else
		printf("No Answer\n0");
	return 0;
}

T1408 : 素数回文数的个数

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  求 11 11 11 n n n之间(包括 n n n),既是素数又是回文数的整数有多少个。

【输入】

  一个大于 11 11 11小于 1000 1000 1000的整数 n n n

【输出】

   11 11 11 n n n之间的素数回文数个数。

【输入样例】

23

【输出样例】

1

【答案&代码】

#include
#include
#include
bool isPrime(int num){
	for(int i=2;i<=sqrt(num);i++)
		if(num%i==0)
			return false;
	return true;
}
bool huiwen(int num){
	char str[5];
	sprintf(str,"%d",num);
	for(int i=0,j=strlen(str)-1;i<=j;i++,j--){
		char temp=str[i];
		str[i]=str[j];
		str[j]=temp;
	}
	int newnum;
	sscanf(str,"%d",&newnum);
	return num==newnum;
}
int main(void){
	int n;
	scanf("%d",&n);
	int sum=0;
	for(int i=11;i<=n;i++)
		if(isPrime(i)&&huiwen(i))
			sum+=1;
	printf("%d",sum);
	return 0;
}

T1409 : 判决素数个数

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  输入两个整数 X X X Y Y Y,输出两者之间的素数个数(包括 X X X Y Y Y)。

【输入】

  两个整数 X X X Y ( 1 ≤ X , Y ≤ 1 0 5 ) Y(1≤X,Y≤10^{5}) Y(1X,Y105)

【输出】

  输出一个整数,表示 X , Y X,Y X,Y之间的素数个数(包括 X X X Y Y Y)。

【输入样例】

1 100

【输出样例】

25

【答案&代码】

#include
#include
#include
bool isprime(int num){
	if(num==0||num==1)
		return false;
	for(int i=2;i<=sqrt(num);i++)
		if(num%i==0)
			return false;
	return true;
}
int main(void){
	int x,y;
	scanf("%d%d",&x,&y);
	int sum=0;
	for(;x<=y;x++)
		if(isprime(x))
			sum+=1;
	printf("%d",sum);
	return 0;
}

T1410 : 最大质因子序列

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  任意输入两个正整数 m , n ( 1 < m < n ≤ 5000 ) m,n(1<m<n≤5000) m,n(1<m<n5000),依次输出 m m m n n n之间每个数的最大质因子(包括 m m m n n n,如果某个数本身是质数,则输出这个数自身)。

【输入】

  一行,包含两个正整数 m m m n n n,其间以单个空格间隔。

【输出】

  一行,每个整数的最大质因子,以逗号间隔。

【输入样例】

5 10

【输出样例】

5,3,7,2,3,5

【答案&代码】

#include
#include
int fun(int num){
	int temp=1;
	for(int i=2;i<=num;i++)
		if(num%i==0){
			temp=i;
			num/=i;
			i=1;
		}
	return temp==1?num:temp;
}
int main(void){
	int m,n;
	scanf("%d%d",&m,&n);
	printf("%d",fun(m));
	for(int i=m+1;i<=n;i++)
		printf(",%d",fun(i));
	return 0;
}

T1411 : 区间内的真素数

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  找出正整数 M M M N N N之间( N N N不小于 M M M)的所有真素数。

真素数的定义:如果一个正整数 P P P为素数,且其反序也为素数,那么 P P P就为真素数。

【输入】

  输入两个数 M M M N N N,空格间隔, 1 ≤ M ≤ N ≤ 100000 1≤M≤N≤100000 1MN100000

【输出】

  按从小到大输出 M M M N N N之间(包括 M M M N N N)的真素数,逗号间隔。如果之间没有真素数,则输出No

【输入样例】

10 35

【输出样例】

11,13,17,31

【答案&代码】

#include
#include
#include
int numfz(int num){
	char str[8];
	sprintf(str,"%d",num);
	for(int i=0,j=strlen(str)-1;i<=j;i++,j--){
		char temp=str[i];
		str[i]=str[j];
		str[j]=temp;
	}
	int newn;
	sscanf(str,"%d",&newn);
	return newn;
}
bool isprime(int num){
	if(num<2)
		return false;
	for(int i=2;i<=sqrt(num);i++)
		if(num%i==0)
			return false;
	return true;
}
int main(void){
	int m,n;
	scanf("%d%d",&m,&n);
	int sum=0;
	bool flag=true;
	for(;m<=n;m++)
		if(flag&&isprime(m)&&isprime(numfz(m))){
			flag=false;
			printf("%d",m);
		}
		else if(isprime(m)&&isprime(numfz(m)))
			printf(",%d",m);
	if(flag)
		printf("No");
	return 0;
}

T1412 : 二进制分类

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  若将一个正整数化为二进制数,在此二进制数中,我们将数字 1 1 1的个数多于数字 0 0 0的个数的这类二进制数称为 A A A类数,否则就称其为 B B B类数。

  程序要求:求出 1 − 1000 1-1000 11000之中(包括 1 1 1 1000 1000 1000),全部 A , B A,B A,B两类数的个数。

【输入】

  (无)

【输出】

  一行,包含两个整数,分别是 A A A类数和 B B B类数的个数,中间用单个空格隔开。

【输入样例】

(无)

【输出样例】

(无)

【答案&代码】

#include
void change_to_2(int num,int result[16]){
	for(int i=0;i<16;i++)
		result[i]=0;
	result[0]=num;
	for(int i=0;i<16;i++)
		if(result[i]>=2)
			result[i+1]+=result[i]/2,result[i]%=2;
	return;
}
bool A_or_B(int num[16]){
	int sum0=0,sum1=0;
	int top=0;
	for(int i=15;i>=0;i--)
		if(num[i]!=0){
			top=i;
			break;
		}
	for(int i=top;i>=0;i--){
		if(num[i]==0)
			sum0++;
		else
			sum1++;
	}
	return sum1>sum0;
}
int main(void){
	int suma=0,sumb=0;
	for(int i=1,result[16]={0};i<=1000;i++){
		change_to_2(i,result);
		if(A_or_B(result))
			suma++;
		else
			sumb++;
	}
	printf("%d %d",suma,sumb);
	return 0;
}

T1413 : 确定进制

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  你的任务是写一段程序,读入三个整数 p , q , r p,q,r p,q,r,然后确定一个进制 B ( 2 ≤ B ≤ 40 ) B(2≤B≤40) B(2B40)使得 p × q = r p×q=r p×q=r。如果 B B B有很多选择,输出最小的一个。

【输入】

  一行,包含三个整数 p , q , r p,q,r p,q,r p , q , r p,q,r p,q,r的所有位都是数字,并且 1 ≤ p , q , r ≤ 1 , 000 , 000 1≤p,q,r≤1,000,000 1p,q,r1,000,000

【输出】

  一个整数:即使得 p × q = r p×q=r p×q=r成立的最小的 B B B。如果没有合适的 B B B,则输出 0 0 0

【输入样例】

6 9 42

【输出样例】

13

【答案&代码】

#include
using namespace std;
int judge(int x,int B);

int main()
{
	int a,b,c;
	int i;

	cin>>a>>b>>c;
	for(i=2;i<=40;i++)
		if(judge(a,i)*judge(b,i)==judge(c,i))
		{
			cout<<i<<endl;
			return 0;
		}
	cout<<0<<endl;
	return 0;
}

int judge(int x,int B){
	int value=1,num=0;
	while(x){
		num+=((x%10)*value);
		value*=B;
		x/=10;
	}
	return num;
}

第二节 递归算法

T1158 : 求1+2+3+…

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  用递归的方法求 1 + 2 + 3 + . . . + N 1+2+3+...+N 1+2+3+...+N的值。

【输入】

  输入 N N N

【输出】

  输出和。

【输入样例】

5

【输出样例】

15

【答案&代码】

#include
int fun(int num){
	if(num==1)
		return 1;
	else
		return num+fun(num-1);
}
int main(void){
	int n;
	scanf("%d",&n);
	printf("%d",fun(n));
	return 0;
}

T1159 : 斐波那契数列

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  用递归函数输出斐波那契数列第 n − 1 n-1 n1项。

【输入】

  一个正整数 n n n

【输出】

  第 n − 1 n-1 n1项是多少。

【输入样例】

3

【输出样例】

1

【答案&代码】

#include
int fun(int num){
	if(num==1)
		return 0;
	else if(num==2||num==3)
		return 1;
	else
		return fun(num-2)+fun(num-1);
}
int main(void){
	int n;
	scanf("%d",&n);
	printf("%d",fun(n));
	return 0;
}

T1160 : 倒序数

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  输入一个非负整数,输出这个数的倒序数。

【输入】

  输入一个非负整数(保证个位不为零)。

【输出】

  输出倒序的数。

【输入样例】

123

【输出样例】

321

【答案&代码】

#include
#include
int main(void){
	char num[512];
	scanf("%s",num);
	for(int i=strlen(num)-1;i>=0;i--)
		printf("%c",num[i]);
	return 0;
}

T1161 : 转进制

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  用递归算法将一个十进制数 X X X转换成任意进制数 M ( M ≤ 16 ) M(M≤16) M(M16)

【输入】

  一行两个数,第一个十进制数 X X X,第二个为进制 M M M

【输出】

  输出结果。

【输入样例】

31 16

【输出样例】

1F

【答案&代码】

#include
void change_to_n(int num,int result[32],int n){
	for(int i=0;i<32;i++)
		result[i]=0;
	result[0]=num;
	for(int i=0;i<32;i++)
		if(result[i]>=n)
			result[i+1]+=result[i]/n,result[i]%=n;
	return; 
} 
void Print(int num[32]){
	int top=0;
	for(int i=31;i>=0;i--)
		if(num[i]!=0){
			top=i;
			break;
		}
	for(int i=top;i>=0;i--)
		if(num[i]<10)
			printf("%d",num[i]);
		else
			printf("%c",num[i]-10+'A');
	return;
}
int main(void){
	int x,m;
	scanf("%d%d",&x,&m);
	int num[32]={0};
	change_to_n(x,num,m);
	Print(num);
	return 0;
}

T1162 : 字符串逆序

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  输入一串以!结束的字符,按逆序输出。

【输入】

  如题述。

【输出】

  如题述。

【输入样例】

abc!

【输出样例】

cba

【答案&代码】

#include
#include
int main(void){
	int m,n;
	char str[512];
	char temp;
	int i=0;
	do{
		scanf("%c",&temp);
		str[i]=temp;
		i++;
	}while(temp!='!');
	str[i-1]='\0';
	for(i=strlen(str)-1;i>=0;i--)
		printf("%c",str[i]);
	return 0;
}

T1163 : 阿克曼(Ackmann)函数

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  Ackmann函数 A ( m , n ) ( m ≤ 3 , n ≤ 10 ) A(m,n)(m≤3,n≤10) A(m,n)(m3,n10)中,函数值定义为:

a k m ( m , n ) = { n + 1   ( m = 0 ) a k m ( m − 1 , 1 )   ( m > 0 , n = 0 ) a k m ( m − 1 , a k m ( m , n − 1 ) )   ( m , n > 0 ) akm(m,n)=\begin{cases}n+1\ (m=0)\\akm(m-1,1)\ (m>0,n=0)\\akm(m-1,akm(m,n-1))\ (m,n>0)\end{cases} akm(m,n)=n+1 (m=0)akm(m1,1) (m>0,n=0)akm(m1,akm(m,n1)) (m,n>0)

【输入】

  输入 m m m n n n

【输出】

  函数值。

【输入样例】

2 3

【输出样例】

9

【答案&代码】

#include
int A(int m,int n){
	if(m==0)
		return n+1;
	else if(m>0&&n==0)
		return A(m-1,1);
	else
		return A(m-1,A(m,n-1));
}
int main(void){
	int m,n;
	scanf("%d%d",&m,&n);
	printf("%d",A(m,n));
	return 0;
}

T1164 : digit函数

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  在程序中定义一函数 d i g i t ( n , k ) digit(n,k) digit(n,k),它能分离出整数 n n n从右边数第 k k k个数字。

【输入】

  正整数 n n n k k k

【输出】

  一个数字。

【输入样例】

31859 3

【输出样例】

8

【答案&代码】

#include
#include
void digit(int n,int k){
	char str[16];
	sprintf(str,"%d",n);
	if(k>strlen(str))
		printf("0");
	else
		printf("%c",str[strlen(str)-k]);
	return;
}
int main(void){
	int n,k;
	scanf("%d%d",&n,&k);
	digit(n,k);
	return 0;
}

T1165 : Hermite多项式

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  用递归的方法求Hermite多项式的值

h n ( x ) = { 1   ( n = 0 ) 2 x   ( n = 1 ) 2 x h n − 1 ( x ) − 2 ( n − 1 ) h n − 2 ( x )   ( n > 1 ) h_{n}(x)=\begin{cases}1\ (n=0)\\2x\ (n=1)\\2xh_{n-1}(x)-2(n-1)h_{n-2}(x)\ (n>1)\end{cases} hn(x)=1 (n=0)2x (n=1)2xhn1(x)2(n1)hn2(x) (n>1)

  对给定的 x x x和正整数 n n n,求多项式的值。

【输入】

  给定的 n n n和正整数 x x x

【输出】

  多项式的值。

【输入样例】

1 2

【输出样例】

4.00

【答案&代码】

#include
double h(double n,double x){
	if(n==0)
		return 1;
	else if(n==1)
		return 2*x;
	else
		return 2*x*h(n-1,x)-2*(n-1)*h(n-2,x);
}
int main(void){
	double n,x;
	scanf("%lf%lf",&n,&x);
	printf("%.2f",h(n,x));
	return 0;
}

T1166 : 求f(x,n)

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  已知

f ( x , n ) = n + n − 1 + . . . + 2 + 1 + x f(x,n)=\sqrt{n+\sqrt{n-1+\sqrt{...+2+\sqrt{1+x}}}} f(x,n)=n+n1+...+2+1+x

【输入】

  输入 x x x n n n

【输出】

  函数值,保留两位小数。

【输入样例】

4.2 10

【输出样例】

3.68

【答案&代码】

#include  
#include  
#include  
using namespace std;  
double calculate(double x,double n);  
  
int main()  
{  
    double n,x;  
    double result;  
    cin>>x>>n;  
    result=calculate(x,n);  
    printf("%.2lf\n",result);  
    return 0;  
}  
  
double calculate(double x,double n)  
{  
    if(n==1)//判断是否到达递归边界n=1  
        return sqrt(1+x);  
    else//否则继续递归  
        return sqrt(n+calculate(x,n-1));  
} 

T1167 : 再求f(x,n)

时间限制: 1000 ms 内存限制: 65536 KB

【题目描述】

  已知

f ( x , n ) = x n + x n − 1 + x . . . + x 1 + x f(x,n)=\frac{x}{n+\frac{x}{n-1+\frac{x}{...+\frac{x}{1+x}}}} f(x,n)=n+n1+...+1+xxxxx

  用递归函数求解。

【输入】

  第一数是 x x x的值,第二个数是 n n n的值。

【输出】

  函数值。

【输入样例】

1 2

【输出样例】

0.40

【答案&代码】

#include
double f(double x,double n){
	if(n==1)
		return x/(n+x);
	return x/(n+f(x,n-1));
}
int main(void){
	double x,n;
	scanf("%lf%lf",&x,&n);
	printf("%.2f",f(x,n));
	return 0;
}

你可能感兴趣的:(C++语言)