1001 害死人不偿命的(3n+1)猜想 (15 分)
卡拉兹(Callatz)猜想:对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 (3n+1) 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 n=1。卡拉兹在 1950 年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证 (3n+1),以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……
我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过 1000 的正整数 n,简单地数一下,需要多少步(砍几下)才能得到 n=1?
输入格式:每个测试输入包含 1 个测试用例,即给出正整数 n 的值。
输出格式:输出从 n 计算到 1 需要的步数。
输入样例:3
输出样例:
5
答案:
#include<stdio.h>
int main()
{
int n,count=0;
scanf("%d",&n);
while(n!=1){
if(n%2==0){
n=n/2;
}else{
n=(3*n+1)/2;
}
count++;
}
printf("%d",count);
return 0;
}
1004 成绩排名 (20 分)读入 n(>0)名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。
输入格式:每个测试输入包含 1 个测试用例,格式为
第 1 行:正整数 n
第 2 行:第 1 个学生的姓名 学号 成绩
第 3 行:第 2 个学生的姓名 学号 成绩
... ... ...
第 n+1 行:第 n 个学生的姓名 学号 成绩其中姓名和学号均为不超过 10 个字符的字符串,成绩为 0 到 100 之间的一个整数,这里保证在一组测试用例中没有两个学生的成绩是相同的。
输出格式:对每个测试用例输出 2 行,第 1 行是成绩最高学生的姓名和学号,第 2 行是成绩最低学生的姓名和学号,字符串间有 1 空格。
输入样例:3
Joe Math990112 89
Mike CS991301 100
Mary EE990830 95输出样例:
Mike CS991301
Joe Math990112
答案:
#include<stdio.h>
struct student{
char name[11];
char num[11];
int grade;
}stu[101];//题目给出一个测试用例中不会出现重复的成绩,成绩大于0小于等于100,所以,一个测试用例最多101个元素
int main()
{
int n,i;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%s %s %d",&stu[i].name,&stu[i].num,&stu[i].grade);
}
int min=stu[0].grade,max=stu[0].grade;
int x,y;
for(i=0;i<n;i++){
if(stu[i].grade>=max){
max=stu[i].grade;
x=i;
}
if(stu[i].grade<=min){
min=stu[i].grade;
y=i;
}
}
printf("%s %s\n",stu[x].name,stu[x].num);
printf("%s %s\n",stu[y].name,stu[y].num);
return 0;
}
1006 换个格式输出整数 (15 分)
让我们用字母 B 来表示“百”、字母 S 表示“十”,用 12...n 来表示不为零的个位数字 n(<10),换个格式来输出任一个不超过 3 位的正整数。例如 234 应该被输出为 BBSSS1234,因为它有 2 个“百”、3 个“十”、以及个位的 4。
输入格式:每个测试输入包含 1 个测试用例,给出正整数 n(<1000)。
输出格式:每个测试用例的输出占一行,用规定的格式输出 n。
输入样例 1:234
输出样例 1:
BBSSS1234
输入样例 2:
23
输出样例 2:
SS123
答案:
#include<stdio.h>
int main()
{
int n,i;
int b,s,g;
scanf("%d",&n);
b=n/100;
s=n/10%10;
g=n%10;
for(i=0;i<b;i++){
printf("B");
}
for(i=0;i<s;i++){
printf("S");
}
for(i=1;i<=g;i++){
printf("%d",i);
}
return 0;
}
1008 数组元素循环右移问题 (20 分)一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A0A1⋯AN−1)变换为(AN−M⋯AN−1A0A1⋯AN−M−1)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?
输入格式:每个输入包含一个测试用例,第1行输入N(1≤N≤100)和M(≥0);第2行输入N个整数,之间用空格分隔。
输出格式:在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。
输入样例:6 2
1 2 3 4 5 6输出样例:
5 6 1 2 3 4
答案:
#include <stdio.h>
int main()
{
int a[200];
int N,M,i,j;
scanf("%d %d",&N,&M);
for(i=0;i<N;i++){
scanf("%d",&a[i]);
}
for(i=0;i<N;i++){
j=(M%N+i)%N+100;//为了防止输入的M大于100,M%N可以解决循环的周期问题,减少循环次数
a[j]=a[i];
}
for(i=0;i<N;i++){
if(i!=N-1){ //if判断解决的是输出格式问题
printf("%d ",a[i+100]);
}else{
printf("%d",a[i+100]);
}
}
return 0;
}
1009 说反话 (20 分)给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。
输入格式:测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用 1 个空格分开,输入保证句子末尾没有多余的空格。
输出格式:每个测试用例的输出占一行,输出倒序后的句子。
输入样例:Hello World Here I Come
输出样例:
Come I Here World Hello
答案:
#include<stdio.h>
int main()
{
char str[85][85];
int i=0,j,length=0;
char c;
while((c=getchar())!='\n'){
if(c!=' '){
str[length][i]=c;
i++;
}else{
str[length][i]='\0';
length++;
i=0;
continue;
}
}
str[length][i]='\0';
for(i=length;i>=0;i--){
if(str[i]!='\0'){
printf("%s ",str[i]);
}else{
printf("%s",str[i]);
}
}
return 0;
}
1011 A+B 和 C (15 分)
给定区间 [−231,231] 内的 3 个整数 A、B 和 C,请判断 A+B 是否大于 C。
输入格式:输入第 1 行给出正整数 T (≤10),是测试用例的个数。随后给出 T 组测试用例,每组占一行,顺序给出 A、B 和 C。整数间以空格分隔。
输出格式:对每组测试用例,在一行中输出 Case #X: true 如果 A+B>C,否则输出 Case #X: false,其中 X 是测试用例的编号(从 1 开始)。
输入样例:4
1 2 3
2 3 4
2147483647 0 2147483646
0 -2147483648 -2147483647输出样例:
Case #1: false
Case #2: true
Case #3: true
Case #4: false
答案:
#include<stdio.h>
int main()
{
int T,i;
long A,B,C;
scanf("%d",&T);
for(i=1;i<=T;i++){
scanf("%ld %ld %ld",&A,&B,&C);
if(A+B>C){
printf("Case #%d: true\n",i);
}else{
printf("Case #%d: false\n",i);
}
}
return 0;
}
1016 部分A+B (15 分)
正整数 A 的“DA(为 1 位整数)部分”定义为由 A 中所有 DA 组成的新整数 PA。例如:给定 A=3862767,DA=6,则 A 的“6 部分”PA 是 66,因为 A 中有 2 个 6。
现给定 A、DA、B、DB,请编写程序计算 PA+PB。
输入格式:输入在一行中依次给出 A、DA、B、DB,中间以空格分隔,其中 0<A,B<10^10。
输出格式:在一行中输出 PA+PB 的值。
输入样例 1:3862767 6 13530293 3
输出样例 1:
399
输入样例 2:
3862767 1 13530293 8
输出样例 2:
0
答案:
#include<stdio.h>
long long fun(long long A,int Da)
{
long long sum=0;
while(A){
if(Da==A%10)
sum=sum*10+Da;//还原要求的重复数字,必须在sum上乘10,才能进位。
A=A/10;//每次减少一位数,为了取得A的每一位数字
}
return sum;
}
int main()
{
long long int A,B;//10^10表示的数是11位数,用long long int 来表示输入的数,2^63
int Da,Db;
scanf("%lld %d %lld %d",&A,&Da,&B,&Db);
printf("%lld",(fun(B,Db)+fun(A,Da)));
return 0;
}