目录
题目来源《算法笔记》
1、简单模拟
(1)
题目描述:
对于任何一个自然数n,如果它是偶数,那么把它砍断一半;如果它是奇数,那么把(3n+1)砍掉一半。这样一直反复看下去,最后一定在某一步得到n=1。请设计算一下任意一个不超过1000的正整数n,简单的数一下要多少步才能得到n=1?
输入样例:
3
输出样例:
5
思路:读入题目给出的n,之后用while循环语句反复判断n是否为1;
- 如果n为1,则退出循环。
- 如果n不为1,则判断n是否为偶数,如果是偶数,则令n除以2;否则令n为(3*n+1)/2。之后令计数器step加1。
代码如下:
#include<stdio.h>
int main()
{
int n, step = 0;
scanf("%d", &n);
while (n != 1)
{
if (n % 2 == 0) n = n / 2; //如果是偶数
else n = (3 * n + 1) / 2; //如果是奇数
step++;
}
printf("%d\n", step);
return 0;
}
(2)
题目描述:
在第1行给出不超过10000的正整数N,即参赛人数。随后N行,每行给出一位参赛者的信息和战绩,包括其所代表的学校编号(从1开始连续编号)及其比赛成绩(百分制),中间以空格分隔。然后输出总得分最高的学校编码及分数。
输入样例:
5
3 68
2 70
1 100
2 80
3 40
输出样例:
2 150
思路:
- 令数组school【maxn】记录每个学校的总分,初值为0。对每一个读入的学校schID与其对应的分数score,令school【schID】+=score。
- 令变量k记录最高分的学校编号,变量MAX记录最高总分,初值为-1。由于学校是连续编号的,因此枚举编号1~N,不断更新k和MAX即可。
代码如下:
#include<stdio.h>
const int maxn = 10000;
int school[maxn] = { 0 };//记录每个学校的总分
int main()
{
int n, schID, score;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%d%d", &schID, &score);
school[schID] += score;
}
int k = 1, MAX = -1;
for (int i = 1; i < n; i++)
{
if(school[i]>MAX)
{
MAX = school[i];
k = i;
}
}
printf("%d %d\n", k, MAX);
return 0;
}
2、查找元素
题目描述:
输入一个数n(1<=n<=100),然后输入n个数值各不相同的数,再输入一个值x,输出这个值在这个数组中的下标啊(从0开始,若不在数组中则输出-1)
输入样例:
4
1 2 3 4
3
输出样例:
2
代码如下;
#include<stdio.h>
const int maxn = 100;
int a[maxn];
int main()
{
int n, x;
while (scanf("%d", &n) != EOF)
{
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]); //输入n个数
}
scanf("%d", &x); //输入欲查询的数
int k; //下标
for (k = 0; k < n; k++)
{
if (a[k] == x) {
printf("%d\n", k);
break;
}
}
if (k == n) //如果没有找到
{
printf("-1\n"); //输出-1
}
}
return 0;
}
3、图形输出
题目描述:
在一行中给出正方形边长N(3<=N<=20)和组成正方形边的某种字符C,间隔一个空格。由给定字符C画出的正方形。但是注意到行间比列间距大,所以为了让结果看上去更像正方形,所输出的行数实际是列数的50%(四舍五入取整)
输入样例:
10 a
输出样例:
aaaaaaaaaa
a a
a a
a a
aaaaaaaaaa
代码如下:
#include<stdio.h>
int main()
{
int row, col; // 行,列
char c;
scanf("%d %c", &col, &c); //输入行数,欲执行的字符
if (col % 2 == 1) row = col / 2 + 1; //col为奇数,向上取整
else row = col / 2; //col为偶数
for (int i = 0; i < col; i++)
{
printf("%c", c);
}
printf("\n");
//第2到row-1行
for (int i = 2; i < row; i++)
{
printf("%c", c); //每行第一个a
for (int j = 0; j < col - 2; j++)
{
printf(" "); //col-2个字符
}
printf("%c\n", c);
}
//第row行
for (int i = 0; i < col; i++)
{
printf("%c", c); //col个字符
}
return 0;
}
4、日期处理
题目描述:
有两个日期,求两个日期之间的天数,如果两个日期是连续的,则规定它们之间的天数为两天。
输入样例:
20130101
20130105
输出样例:
5
代码如下:
#include<stdio.h>
int month[13][2] = { {0,0},{31,31},{28,29},{31,31},{30,30},{31,31},{30,30},{31,31},
{31,31},{30,30},{31,31},{30,30},{31,31} };
bool isLeap(int year) { //判断是否为闰年
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
int main()
{
int time1, y1, m1, d1;
int time2, y2, m2, d2;
while (scanf("%d%d", &time1, &time2) != EOF)
{
if (time1 > time2) { //第一日期晚于第二个日期,则交换
int temp = time1;
time1 = time2;
time2 = temp;
}
y1 = time1 / 10000, m1 = time1 % 10000 / 100; d1 = time1 % 100;
y2 = time2 / 10000, m2 = time2 % 10000 / 100; d2 = time2 % 100;
int ans = 1; //记录结果
//第一个日期没有达到第二个日期进行循环
while (y1 < y2 || m1 < m2 || d1 < d2) {
d1++; //天数加一
if (d1 == month[m1][isLeap(y1)] + 1) //满当月天数
{
m1++; //日期变为下个月的1号
d1 = 1;
}
if (m1 == 13) { //月份满12个月
y1++; //日期变为下一年的1月
m1 = 1;
}
ans++; //累计
}
printf("%d\n", ans); //输出结果
}
return 0;
}
5、进制转换
题目描述:
输入两个非负十进制数A和B,以及D(进制数),输出A+B的D进制数。
输入样例:
123 456 8
输出样例:
1103
代码如下:
#include<stdio.h>
int main()
{
int a, b, d;
scanf("%d%d%d", &a, &b, &d);
int sum = a + b;
int ans[31], num = 0; //ans存放D进制的每一位
do //进制转换
{
ans[num++] = sum % d;
sum /= d;
} while (sum != 0);
for (int i = num - 1; i >= 0; i--) //从高位到低位进行输出
{
printf("%d", ans[i]);
}
return 0;
}
6、字符串处理
(1)判断是否为回文串
题目描述:
读入一个字符串,判断是否是“回文串”,回文串是一个正读和反读都一样的字符串,比如“level”或者“noon”就是回文串。
输入样例:
12321
输出样例:
YES
代码如下:
#include<stdio.h>
#include<cstring>
const int maxn = 256;
//判断是否为回文串
bool judge(char str[]) {
int len = strlen(str); //字符串长度
for (int i = 0; i < len / 2; i++) //i枚举字符串的前一半
{
if (str[i] != str[len - 1 - i]) //判断对称位置是否相同
{
return false; //不是回文串
}
}
return true;
}
int main()
{
char str[maxn];
while (gets(str)) { //读入字符串
bool flag = judge(str); //判断字符串是不是回文串
if (flag == true) {
printf("YES\n");
}
else {
printf("NO\n");
}
}
return 0;
}
(2)反向输出给定的英文
题目描述:
给定一句英语,要求编写程序,将句中的所有单词颠倒顺序输出。
输入样例:
Hello world Here I Come
输出样例:
Come I Here World Hello
代码如下:
#include<stdio.h>
#include<cstring>
int main()
{
char str[90];
gets(str);
int len = strlen(str), r = 0, h = 0;
char ans[90][90];
for (int i = 0; i < len; i++)
{
if (str[i] != ' ') {
ans[r][h++] = str[i];
}
else
{
ans[r][h] = '\0';
r++;
h = 0;
}
}
for (int i = r; i >= 0; i++)
{
printf("%s",ans[i]);
if (i > 0) printf(" ");
}
return 0;
}