15331281 本人学院
EasyNumbers(for lab)
Description:
There are N numbers in a line.And you can change some numbers to B. We want to know the maximum of the sum of these numbers.
input format
The first line is two numbers N and B.
The next line contains N numbers. All the numbers in the input will not exceeding 10000.output format
the answer
sample input
5 3
1 2 3 4 5
sample output
18
MY ANSWER
#include<stdio.h>
int main() {
int N, b, counter;
int c = 0; int sum = 0;
scanf("%d%d", &N, &b);
int g;
scanf("%d", &g);
for (counter = 1; counter <= N; counter++) {
if (g < b) {
g = b;
}
sum += g;
scanf("%d", &g);
}
printf("%d\n", sum);
return 0;
}
THE STANDARD ANSWER
#include<stdio.h>
int main() {
int n, ans = 0, m, i;
scanf("%d%d", &n, &m);
for (i = 1; i <= n; i++) {
int x;
scanf("%d", &x);
if (x < m) x = m;
ans += x;
}
printf("%d\n", ans);
return 0;
}
反馈
这个题呢,难就难在理解题意,理解了之后就没啥事了.就是把那组数里头比B小的数全换成B,再求这组数的和
Simple Caesar’s code(for lab)
You should encrypt a plain text(which contains A-Z,a-z) to a cipher text(which contains A-Z).
The encrypting rule:
1. convert the lowercase to the upper case. for example, ‘h’–>’H’.
If the character is lower case or space, you should not to do that.
2. cycle shift n position. for example, if n =2, then ‘z’ –> ‘B’, ‘H’–>’J’, ‘h’–>’J’.
If the character is space, you should not to do that.
Input format:
n –> stand for how many position you should cycle shift.(1 <= n <= 25)
plain text –>the string you should encrypt(1<= it’s length <= 30)
output format:
cipher text –> not ‘\n’ this time
For example
[Input]
2
ILoveYou
[Output]
KNQXGAQW
HINT
1.如果用getchar接收字符进行移位处理,那么在用scanf接收变量n后,getchar接收字符前,需要用一个getchar函数接收变量n后面的’\n’字符.
2.如果用char数组接收字符串,再逐个处理。 那么不需考虑1中的问题.
为了更好的理解getchar与scanf的区别,本次建议使用第一种方式解题。
tips(题目可能有些超出目前学的知识,所以给出下面的提示):
1.输入的字符串,仅包含A-Z,a-Z.末尾为’\n’。不要考虑包含空格、\t等复杂情况
2.A-Z(ascii十进制:65-90)
a-z(ascii十进制97-122)
3.输出字符的方式,例如:
char c = ‘A’;
printf(“%c”, c);
4.接收一串字符直到遇到换行符结束的代码实现:
char c;
while ((ch = getchar()) != ‘\n’) {
// ….. 对字符进行处理
}
5.输入的结果后面不需要加换行符’\n’
6. ‘Y’ 右移两位是’A’,需要考虑这种特殊情况
MY ANSWER1
这道题目,由于刚开始我分类不当,太着急,所以复杂化了,所以在课堂上一直没有做出来,把自己给绕进去了.
我的做法是,不管大小写,先移位,再把小写转为大写,这样就出现了四种情况
#include<stdio.h>
int main() {
int n;
scanf("%d", &n);
char j = getchar();
char x = getchar();
while (x != '\n') {
if (x <= (90 - n)) {
x += n;
} else if (x < 'a' && x > (90 - n)) {
x = x + n + 6 - 32;
} else if (x >= 'a' && x <= (122 - n)) {
x = x + n - 32;
} else if (x > (122 - n)) {
x = 'A' + n - (122 - x) - 1;
}
printf("%c", x);
x = getchar();
}
return 0;
}
MY ANSWER2
后来,听露露说了一下,发现上面的做法和 先将小写转为大写,再移位 是一样的,但后者明显更简便,因为只要转为大写之后,只需区分两种情况
#include<stdio.h>
int main() {
int n;
scanf("%d", &n);
char j = getchar();
char x = getchar();
while (x != '\n') {
if (x <= 122 && x >= 97) {
x -= 32;
}
if (x > 'Z' - n) {
x = 'A' + n - ('Z' - x) - 1;
} else {
x += n;
}
printf("%c", x);
x = getchar();
}
return 0;
}
THE STANDARD ANSWER
#include <stdio.h>
int main() {
char ch;
int n;
scanf("%d", &n);
getchar(); // 该语句用于接收scanf输入n后的回车
while ((ch = getchar()) != '\n') {
if (ch >= 'a' && ch <= 'z') // 小写转换成大写
ch -= ('a' - 'A');
ch += n; // 移位操作
if (ch > 'Z') // 循环移位
ch = ch - 'Z' - 1 + 'A';
printf("%c", ch);
}
return 0;
}
反馈
经验一:读完题后,先冷静地想好算法,不要着急的打码,这样只会使自己混乱
经验二:用 ‘A’ ‘Z’ 比用它相应的ascii码更有可读性
seven (for hw)
Erin 正在和小伙伴们玩“报7” 游戏,规则很简单:
每一次游戏,小伙伴都要从1开始报数,当报到的数为7的倍数(如7、14、210等),或者报到数在其数字中含有7时(如17、74、272,728等),就需要拍手表示跳过。
Erin想知道当报数上限为n时,在哪些数字需要拍手?
Input:
25
Output:
7 14 17 21
Input:
100
Output:
7 14 17 21 27 28 35 37 42 47 49 56 57 63 67 70 71 72 73 74 75 76 77 78 79 84 87 91 97 98
hint
1.利用循环语句,判断时用除法(/)和取模(%)
2.n的范围在10~3000之间。
读题
找出一串数里面 7的倍数,与位上有7的数字
提示很重要!
1:非7倍数的数,可用除法和取模来进位与判断
2:告诉了我们最多是四位数,而且千位不可能为7,所以只需要处理个.十.百位
MY ANSWER
#include<stdio.h>
int main() {
int n; int x;
scanf("%d", &n);
for (x = 7; x <= n; x++) {
if ((x % 7) == 0) {
printf("%d ", x);
} else {
int c = x % 1000;
int s1 = c / 100;
int s2 = (c - 100 * s1) / 10;
int s3 = c - 100 * s1 - 10 *s2;
if (s1 == 7 || s2 == 7 || s3 ==7) {
printf("%d ", x);
}
}
}
printf("\n");
return 0;
}
THE STANDARD ANSWER
#include<stdio.h>
int main() {
int n, i = 0;
scanf("%d", &n);
for (i = 1; i <= n; i++) {
if (i%7 == 0) {
printf("%d ", i);
}
else if (i % 10 == 7) {
printf("%d ", i);
}
else if ((i/10) % 10 == 7) {
printf("%d ", i);
}
else if ((i/100) % 10 == 7) {
printf("%d ", i);
}
else if ((i/1000) % 10 == 7) {
printf("%d ", i);
}
}
printf("\n");
return 0;
}
反馈
思路清晰之后还是挺容易做出来的.
简单排序题
给定N(0 < N <100)个正整数,请将这些数按升序排序后输出。
输入有两行:第一行为N。
第二行为N个正整数。
输出为一行,两个数之间用一个空格隔开。
示例:
input: 5
343 34 3 1 99
output:
1 3 34 99 34
Hint:
数组,冒泡排序(或者其他更加优秀的排序算法,anyway,冒泡这道题就够了)。
读题
冒泡排序
冒泡排序算法的运作如下:(从后往前)1
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较
#include <stdio.h>
#define SIZE 8
void bubble_sort(int a[], int n);
void bubble_sort(int a[], int n)
{
int i, j, temp;
for (j = 0; j < n - 1; j++) // 保证第j+1大的数在第n-j位上
for (i = 0; i < n - 1 - j; i++)
// 因为上一轮已经排好了第n-j位,所以只需到n-j-1位即可停止
{
if(a[i] > a[i + 1])
{
temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
}
}
} // 冒泡排序的定义
int main()
{
int number[SIZE] = {95, 45, 15, 78, 84, 51, 24, 12};
int i;
bubble_sort(number, SIZE);
for (i = 0; i < SIZE; i++)
{
printf("%d", number[i]);
}
printf("\n");
}
MY ANSWER
#include<stdio.h>
int main() {
int n, i, y;
scanf("%d", &n);
int a[100];
for (i = 0; i < n; i++) {
scanf("%d", &a[i]);
} // 定义数组
int c1, c2, x;
for (c1 = 0; c1 < n - 1; c1++) {
for (c2 = 0; c2 < n - 1 -c1 ; c2++) {
if (a[c2] > a[c2 + 1]) {
x = a[c2];
a[c2] = a[c2 + 1];
a[c2 + 1] = x;
}
}
} // 冒泡排序
for (y = 0; y < n - 1; y++)
printf("%d ", a[y]);
printf("%d", a[n - 1]);
printf("\n"); // 输出结果
return 0;
}
THE STANDARD ANSWER
#include<stdio.h>
int main(void) {
int num, arr[1000], i, j;
scanf("%d", &num);
for (i = 0; i < num; i++) {
scanf("%d", &arr[i]);
}
for (i = num - 1; i > 0; i--) {
for (j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
printf("%d", arr[0]);
for (i = 1; i < num; i++) {
printf(" %d", arr[i]);
}
printf("\n");
return 0;
}
反馈
其实本来是知道冒泡排序的算法,但是不知道怎么用循环与嵌套,看了百度的例子后还是有点晕,后来像悟空所说,自己写一个数组,按照程序一步步手算,就明白了每一个循环的作用了
factorial(for hw)
Input an integer n (0 < n <= 50), output its factorial in two different ways.
1) calculating the factorial directly. For example 4! = 4 * 3 * 2 * 1;
2) using the Stirling’s formula to get an approximation. Stirling’s formula: n! = (e^(-n)) * (n^n) * sqrt(2*PI*n);
Then output their difference by calling the function fabs();
Each output occupies a line.
PI is defined as 3.14159265359
Sample:
input:
4
output:
24
23.506175
0.493825
读题
这个题目没有啥算法难点,可怕的是精度问题和数据类型.
对于其中了一个测试50的阶乘,这个要炸了的数字,我用了long int ,long long int,unsigned long long int,还是不行,看了下面的评论,所有的数据类型都用double
MY ANSWER
#include<stdio.h>
#include<math.h>
int main() {
double PI = 3.14159265359;
int n, i;
double x = 1;
scanf("%d", &n);
for (i = 1; i <= n; i++) {
x *= i;
}
double y = pow(n, n) * exp(-n) * sqrt(2 * PI * n);
double ans = fabs(x - y);
printf("%.0f\n%.6f\n%.6f\n", x, y, ans);
return 0;
}
THE STANDARD ANSWER
#include<stdio.h>
#include<math.h>
#define PI 3.14159265359
int main() {
int x;
int counter = 0;
double firstAnswer = 1.0;
double secondAnswer = 1.0;
scanf("%d", &x);
for (counter = 0; counter < x; counter++) {
firstAnswer *= (counter + 1);
}
secondAnswer = exp(0 - x) * pow(x, x) * sqrt(2 * PI * x);
printf("%.0lf\n%lf\n", firstAnswer, secondAnswer);
printf("%lf\n", fabs(firstAnswer - secondAnswer));
return 0;
}
反馈
在math.h头文件里面有许多函数,其中包括
exp(x) 求e的x次方
fabs(x) 求x的绝对值
pow(x,y) 求x的y次方
“You must learn to enjoy this experience” (for hw)
In a famous web game, players are able to command their fleets and fight with enemies.
The enemies own a very powerful battleship – the Re Class. She is so powerful that she is able to beat the player’s whole fleet by herself.
Now you know that a Re Class battleship is able to attack N times in a battle. And you have to cost M tons of steel to repair the damage caused by each attack.
So how many tons of steel do you need to fight with a Re Class ?
0 < N, M < 101001, both N and M are integers.
Sample Input
12450
66666
Sample Output
829991700
Hint:高精度乘法
读题
这是一个求大数乘以大数的题,显然,各种数据类型都不能直接装下它们..
所以我已经想到了用数组,每位数单独存,再各自相乘,然而我不知道该如何利用循环来进位
于是..高精度乘法
int main()
{
char n[255]={},m[255]={};
int n1[255]={},m1[255]={},s[510]={};
int i,j,k=0,t,x=0,dig;
int lenn,lenm;
scanf("%s%s",&n,&m);
lenn=strlen(n);
lenm=strlen(m);
for(i=0;i<lenn;i++)
n1[i]=n[i]-48;
for(j=0;j<lenm;j++)
m1[j]=m[j]-48;
for(j=lenm-1;j>=0;j--)
{
t=k;
for(i=lenn-1;i>=0;i--)
{
s[t]+=n1[i]*m1[j];
t++;
}
++k;
dig=t;
}
for(i=0;i<dig;i++)
while(s[i]>=10)
{
s[i]-=10;
++s[i+1];
}
if(s[dig]!=0)
for(i=dig;i>=0;i--)
printf("%d",s[i]);
else
for(i=dig-1;i>=0;i--)
printf("%d",s[i]);
return 0;
}
MY ANSWER
#include<stdio.h>
#include<string.h>
int main() {
int i, j, z;
int a[1001] = {}, b[1001] = {}, c[2003] = {};
char a1[1001] = {}, b1[1001] = {};
scanf("%s%s", &a1, &b1);
int x = strlen(a1);
int y = strlen(b1); // ab数组的长度xy
for (i = 0; i < x; i++)
a[i] = a1[i] - 48;
for (j = 0; j < y; j++)
b[j] = b1[j] - 48; // 将NM每位数赋值给ab数组
int k = 0; int t = 0;
for (i = x - 1; i >= 0; i--) {
t = k;
for (j = y - 1; j >= 0; j--) {
c[t] += a[i] * b[j];
t++;
}
k++;
z = t;
}
for (i = 0; i < z; i++) {
while (c[i] >= 10) {
c[i] -= 10;
c[i + 1]++;
}
}
if (c[z] != 0) {
for (i = z; i >= 0; i--)
printf("%d", c[i]);
} else {
for (i = z - 1; i >= 0; i--)
printf("%d", c[i]);
}
printf("\n");
return 0;
}
当然不是抄的,是自己理解之后跟着打的!
THE STANDARD ANSWER
#include <stdio.h>
#include <string.h>
#define MAXLENGTH (1000+1)
char num1[MAXLENGTH], num2[MAXLENGTH], ans[MAXLENGTH << 1];
unsigned tmp[MAXLENGTH << 1] = { 0 };
int main() {
scanf("%s%s", num1, num2);
int l1 = strlen(num1), l2 = strlen(num2);
int i, j;
for (i = 0; i < l1; ++i)
num1[i] -= '0';
for (j = 0; j < l2; ++j)
num2[j] -= '0';
for (i = 0; i < l1; ++i)
for (j = 0; j < l2; ++j)
tmp[i + j + 1] += num1[i] * num2[j];
for (i = l1 + l2 - 1; i > 0; --i) {
ans[i] = '0' + tmp[i] % 10;
tmp[i-1] += tmp[i] / 10;
}
ans[0] = '0' + tmp[0];
for (i = 0; ans[i] == '0'; ++i)
continue;
printf("%s\n", ans + i);
return 0;
}
反馈
提交之后有个问题:内存错误,需要初始化数组.
原来我定义数组是这样的
int a[1000]
后来改成
int a[1000] = {}
嗯,两种方式都可以,不知道为何这里一定要初始化
小结
这周的一个最大感想就是,打码之前,要先想好大致的结构.
- 来自百度百科 ↩