Homework 1_表面積與體積
代码略,直接公式计算即可!
Homework 2_卡車位置
#include <stdio.h>
int main()
{
int timebefore = 0, timenow = 0, choice;
int x = 0, y = 0;
int direction_x = 0, direction_y = 1;
do
{
//记录上一次转弯的时间
timebefore = timenow;
scanf("%d\n%d", &timenow, &choice);
//向前开车
if (direction_x == 0 && direction_y == 1)
{
y += 10 * (timenow - timebefore);
switch (choice)
{
case 1:
direction_x = -1;
direction_y = 0;
break;
case 2:
direction_x = 1;
direction_y = 0;
break;
default:
break;
}
}
//向后开车
else if (direction_x == 0 && direction_y == -1)
{
y -= 10 * (timenow - timebefore);
switch (choice)
{
case 1:
direction_x = 1;
direction_y = 0;
break;
case 2:
direction_x = -1;
direction_y = 0;
break;
default:
break;
}
}
//向左开车
else if (direction_x == -1 && direction_y == 0)
{
x -= 10 * (timenow - timebefore);
switch (choice)
{
case 1:
direction_x = 0;
direction_y = -1;
break;
case 2:
direction_x = 0;
direction_y = 1;
break;
default:
break;
}
}
//向右开车
else if (direction_x == 1 && direction_y == 0)
{
x += 10 * (timenow - timebefore);
switch (choice)
{
case 1:
direction_x = 0;
direction_y = 1;
break;
case 2:
direction_x = 0;
direction_y = -1;
break;
default:
break;
}
}
} while (choice != 3);
printf("%d %d", x, y);
system("pause");
return 0;
}
Homework 3_鏡子房間
#include <stdio.h>
int main()
{
int w, d, i, j, k, num, i_direction, j_direction;
scanf("%d %d", &w, &d);
int a[d][w];
for(i = 0; i < d; i++)
for(j = 0; j < w; j++)
scanf("%d", &a[i][j]);
//遍历每一个编号,由于两两相对应,其实只需计算一半的就可以了,
//用数组存储每一个编号,值为另一个编号,先都初始化为-1,
//每计算一个,就可以到另一个编号下把这个编号作为值存储,
//当到达那个编号时,判断值不为-1,就说明已经找到该对了,不必去计算了,
//这里偷个小懒,就没有实现该步,思路在这里说明一下,因为还是很容易实现的。
for(k = 0; k < 2 * (w + d); k++)
{
//计算编号对应的i、j
if(k / (w + d) == 0)
{
//最下方,向上走
if(k / w == 0)
{
i = d - 1;
j = k;
i_direction = -1;
j_direction = 0;
}
//最右方,向左走
else
{
i = w + d - 1 - k;
j = w - 1;
i_direction = 0;
j_direction = -1;
}
}
else
{
//最上方,向下走
if((k - w - d)/ w == 0)
{
i = 0;
j = 2 * w + d - 1 - k;
i_direction = 1;
j_direction = 0;
}
//最左方,向右走
else
{
i = k - 2 * w - d;
j = 0;
i_direction = 0;
j_direction = 1;
}
}
//找到另一边时跳出循环
while(1)
{
//出口在上边
if(i < 0)
{
//计算对应的编号
num = 2 * w + d - j - 1;
break;
}
//出口在下边
else if(i > d - 1)
{
//计算对应的编号
num = j;
break;
}
//出口在左边
else if(j < 0)
{
//计算对应的编号
num = 2 * w + d + i;
break;
}
//出口在右边
else if(j > w - 1)
{
//计算对应的编号
num = w + d - i - 1;
break;
}
//还在内部
else
{
//45度角镜子,向上变向右,向右变向上,向下变向左,向左变向下
if(a[i][j] == 1)
{
if(i_direction == -1 && j_direction == 0)
{
i_direction = 0;
j_direction = 1;
}
else if(i_direction == 0 && j_direction == 1)
{
i_direction = -1;
j_direction = 0;
}
else if(i_direction == 1 && j_direction == 0)
{
i_direction = 0;
j_direction = -1;
}
else if(i_direction == 0 && j_direction == -1)
{
i_direction = 1;
j_direction = 0;
}
}
//-45度角镜子,向上变向左,向左变向上,向下变向右,向右变向下
else if(a[i][j] == 2)
{
if(i_direction == -1 && j_direction == 0)
{
i_direction = 0;
j_direction = -1;
}
else if(i_direction == 0 && j_direction == -1)
{
i_direction = -1;
j_direction = 0;
}
else if(i_direction == 1 && j_direction == 0)
{
i_direction = 0;
j_direction = 1;
}
else if(i_direction == 0 && j_direction == 1)
{
i_direction = 1;
j_direction = 0;
}
}
//else if(a[i][j] == 0),方向不变,无需处理
//走到下一步
i += i_direction;
j += j_direction;
}
}
printf("%d ", num);
}
system("pause");
return 0;
}
Homework 4_統一發票兌獎
#include <stdio.h>
int prize(int specialPrizeNumbers[3], int firstPrizeNumbers[3], int myNumber)
{
int i;
for (i = 0; i < 3; i++)
if (myNumber == specialPrizeNumbers[i])
return 2000000;
for (i = 0; i < 3; i++)
if (myNumber == firstPrizeNumbers[i])
return 200000;
for (i = 0; i < 3; i++)
if (myNumber % 10000000 == firstPrizeNumbers[i] % 10000000)
return 40000;
for (i = 0; i < 3; i++)
if (myNumber % 1000000 == firstPrizeNumbers[i] % 1000000)
return 10000;
for (i = 0; i < 3; i++)
if (myNumber % 100000 == firstPrizeNumbers[i] % 100000)
return 4000;
for (i = 0; i < 3; i++)
if (myNumber % 10000 == firstPrizeNumbers[i] % 10000)
return 1000;
for (i = 0; i < 3; i++)
if (myNumber % 1000 == firstPrizeNumbers[i] % 1000)
return 200;
return 0;
}
int main()
{
int i;
int specialPrizeNumbers[3];
int firstPrizeNumbers[3];
int myNumber;
int totalPrize = 0;
for (i = 0; i < 3; i++)
scanf("%d", &(specialPrizeNumbers[i]));
for (i = 0; i < 3; i++)
scanf("%d", &(firstPrizeNumbers[i]));
//按ctrl+c(退出)或ctrl+z(停止)会返回EOF
while (scanf("%d", &myNumber) != EOF)
totalPrize += prize(specialPrizeNumbers, firstPrizeNumbers, myNumber);
printf("%d\n", totalPrize);
system("pause");
return 0;
}
Homework 5_矩陣求解
#include <stdio.h>
#define N 256
// A * x = y,x的解即A-1 * y,使用初等行变换法:( A | y ) -> ( E | A-1 * y )
void upper_solver(double *A, double *x, double *y, int n)
{
// 上三角矩阵每行第一个不为0的数值都变为1.000,即二维数组的[0][0],[1][1]...[n - 1][n - 1],对应到A的[0],[n],[n + n-1],[2*n-1 + n-2],[3*n-3 + n-3]...[]
// 即每一行上的数据都除以该行第一个不为0的数,注意,y中数据对应行的值也要相应的被除。
int i, j, control, first, second, k, find;
double multiple;
for (i = 0, control = n, first = 0; i < n; i++)
{
// 记录倍数
multiple = A[first];
for (j = 0; j < control; j++)
{
A[first + j] /= multiple;
}
y[i] /= multiple;
// 定位到每行第一个不为零的位置
first += control;
control--;
}
// 打印数组A出来观察
k = 0;
for (i = 0; i < n; i++)
{
for (j = 0; j < i; j++)
printf("\t");
for (j = 0; j < n - i; j++)
printf("%8.3lf", A[k++]);
printf("\n");
}
// 循环,从下往上,让每一行的第二、三...到最后一个数字通过减去下一行、下两行...下最后一行的某一个倍数来变为0
// 从n-2行,即倒数第二行开始往上到0行,分别有一列、两列...n-1列需要去减下面的行的倍数来变为0
// 起始为n - 2行(倒数第二行)第二个不为零的位置
second = (n + 3) * (n - 2) / 2 + 1;
control = 3;
for (i = n - 2; i >= 0; i--)
{
// i行共n-i列非零,有后n-i-1列(第二个值不为零的列开始到最后一列)需要减为0
for (j = 0; j < n - i - 1; j++)
{
// 对于i行后n-i-1列(0,1...n-i-2)中的某列,例如k列,关键在于找到以它为0行往下数到的k+1行该列的值,减去倍数变成0即可
// 由于是从下往上的,所以下面的行都已经处理好了,每行都只有一列有非零值了,做减法的时候,其他列减去的都会是零,不会出问题
// 当前需要减为零的位置:second + j,值A[second + j],在i行,(0,1...n-i-2)中的j列,
// 需要到i + j+1行,(0,1...n- (i + j+1) -2)中的0列(即第一个非零值,也是唯一的非零值)找到要减去的值,再算出来倍数,把A[second + j]减为零即可,
// 注意,y中数据对应行的值也要相应的被减,即y[i] -= y[i + j+1] * 倍数。
// 先到本行末尾,即i行,(0,1...n-i-2)中的n-i-2列对应的位置
find = second + n - i - 2;
// 经过中间行,到达目标行前一行末尾
for (k = 0; k < j; k++)
{
find += n - (i + 1 + k);
}
// 到达目标行对应列位置,即该行第一个也是唯一一个非零值所在列(下面的行都处理好了,所以只有对角线上的这一列有非零值)
find += 1;
// 算出倍数
multiple = A[second + j] / A[find];
// 修改A中的值和y中的值
// 等价于"A[second + j] -= A[find] * multiple;"但直接赋值为0更省时间,也更准确(浮点数除法得到multiple除不尽等问题很可能导致结果不准确)
A[second + j] = 0;
y[i] -= y[i + j + 1] * multiple;
}
// 定位到每行第二个不为零的位置
second -= control;
control++;
}
// 最后A变成了E,y变成了A-1 * y
// 打印数组A出来观察,并把现在数组y中的值,即结果A-1 * y存到x中
k = 0;
for (i = 0; i < n; i++)
{
for (j = 0; j < i; j++)
printf("\t");
for (j = 0; j < n - i; j++)
printf("%8.3lf", A[k++]);
printf("\n");
x[i] = y[i];
}
}
int main(void)
{
int i, j;
int n;
double A[N * (N + 1) / 2];
double *aptr = A;
double x[N];
double y[N];
scanf("%d", &n);
for ( i = 0 ; i < n ; i++ )
for ( j = i ; j < n ; j++ ) {
scanf("%lf", aptr);
aptr++;
}
for ( i = 0 ; i < n ; i++ )
scanf("%lf", &(y[i]));
upper_solver(A, x, y, n);
for ( i = 0 ; i < n ; i++ )
printf("%lf ", x[i]);
system("pause");
return 0;
}
另一种更简单的解题方法:
Homework 6_Basic Interpreter
#include <stdio.h>
#define MAX_VAR_NUM 15
#define MAX_VAR_LENGTH 10
#define MAX_SENTENCE_NUM 50
#define MAX_SENTENCE_LENGTH 150
int main()
{
// var和value存储所有变量和对应的值
char var[MAX_VAR_NUM][MAX_VAR_LENGTH], input[MAX_SENTENCE_LENGTH];
memset(var, 0, sizeof(var));
int value[MAX_VAR_NUM], var_num = 0;
scanf("%s", input);
// 不为"END",则继续读取
while (strcmp(input, "END"))
{
// 存储变量值
strcpy(var[var_num], input);
// 跳过等号
scanf("%s", input);
// 读取变量值
scanf("%d", &(value[var_num]));
// 变量个数累加
var_num++;
scanf("%s", input);
}
/*
int i = 0;
for (i = 0; i < var_num; i++)
printf("%s = %d ", var[i], value[i]);
printf("\n");
*/
// sentence存储每行语句,sentence_num存储语句行数(从1开始)
char sentence[MAX_SENTENCE_NUM][MAX_SENTENCE_LENGTH];
memset(sentence, 0, sizeof(sentence));
// 从行一开始!
int sentence_num = 1;
// 把行0,即变量定义那一行的语句最后的'\n'读走跳过
fgets(input, MAX_SENTENCE_LENGTH, stdin);
// 读取一行,到换行或者MAX_SENTENCE_LENGTH截止,这里都是读到换行为止
fgets(input, MAX_SENTENCE_LENGTH, stdin);
// 结尾的'\n'换成'\0'
input[strlen(input) - 1] = '\0';
// 若结尾有多余的空格,注意置为'\0'
while (input[strlen(input) - 1] == ' ')
{
input[strlen(input) - 1] = '\0';
}
// 不为"STOP",则继续读取
while (strcmp(input, "STOP"))
{
// 存储变量值
strcpy(sentence[sentence_num], input);
// 语句行数累加
sentence_num++;
fgets(input, MAX_SENTENCE_LENGTH, stdin);
// 结尾的'\n'换成'\0'
input[strlen(input) - 1] = '\0';
while (input[strlen(input) - 1] == ' ')
{
input[strlen(input) - 1] = '\0';
}
}
// 最后一行语句也要加上!
strcpy(sentence[sentence_num], "STOP");
/*
int i;
for (i = 1; i <= sentence_num; i++)
printf("%s\n", sentence[i]);
*/
int line_now = 1; // 存储当前执行到的语句行数,从1开始计数
// 只要当前没有执行到"STOP"语句
while (line_now != sentence_num)
{
// 解析当前语句
// GOTO 语句
if (sentence[line_now][0] == 'G' && sentence[line_now][1] == 'O' && sentence[line_now][2] == 'T' && sentence[line_now][3] == 'O')
{
int num = 0, pos = 5;
while (sentence[line_now][pos] != '\0')
{
num = num * 10 + sentence[line_now][pos] - '0';
pos++;
}
line_now = num;
}
// IF 语句
else if (sentence[line_now][0] == 'I' && sentence[line_now][1] == 'F')
{
int pos = 3, i = 0, op, value1 = 0, value2 = 0, condition_flag = 0;
char var1[MAX_VAR_LENGTH], var2[MAX_VAR_LENGTH];
memset(var1, 0, sizeof(var1));
memset(var2, 0, sizeof(var2));
// 获取第一个变量名
while (sentence[line_now][pos] != ' ')
{
var1[i] = sentence[line_now][pos];
i++;
pos++;
}
pos++;
// 获取判断元
if (sentence[line_now][pos] == '=' && sentence[line_now][pos + 1] == '=' && sentence[line_now][pos + 2] == ' ')
{
op = 0;
pos += 2;
}
else if (sentence[line_now][pos] == '!' && sentence[line_now][pos + 1] == '=' && sentence[line_now][pos + 2] == ' ')
{
op = 1;
pos += 2;
}
else if (sentence[line_now][pos] == '>' && sentence[line_now][pos + 1] == ' ')
{
op = 2;
pos += 1;
}
else if (sentence[line_now][pos] == '<' && sentence[line_now][pos + 1] == ' ')
{
op = 3;
pos += 1;
}
else if (sentence[line_now][pos] == '>' && sentence[line_now][pos + 1] == '=' && sentence[line_now][pos + 2] == ' ')
{
op = 4;
pos += 2;
}
else if (sentence[line_now][pos] == '<' && sentence[line_now][pos + 1] == '=' && sentence[line_now][pos + 2] == ' ')
{
op = 5;
pos += 2;
}
pos++;
// 获取第二个变量名
i = 0;
while (sentence[line_now][pos] != ' ')
{
var2[i] = sentence[line_now][pos];
i++;
pos++;
}
pos++;
// 根据第一个变量名找到它对应的值大小
for (i = 0; i < var_num; i++)
{
// 找到相同的变量名,strcmp返回值为0
if (strcmp(var[i], var1) == 0)
{
value1 = value[i];
break;
}
}
// 根据第二个变量名找到它对应的值大小
for (i = 0; i < var_num; i++)
{
// 找到相同的变量名,strcmp返回值为0
if (strcmp(var[i], var2) == 0)
{
value2 = value[i];
break;
}
}
// 根据两个变量的值和判断元来看判断句是对还是错
switch (op)
{
case 0:
if (value1 == value2)
condition_flag = 1;
break;
case 1:
if (value1 != value2)
condition_flag = 1;
break;
case 2:
if (value1 > value2)
condition_flag = 1;
break;
case 3:
if (value1 < value2)
condition_flag = 1;
break;
case 4:
if (value1 >= value2)
condition_flag = 1;
break;
case 5:
if (value1 <= value2)
condition_flag = 1;
break;
default:
break;
}
// 判断句正确,则会执行后面的 GOTO 语句,跳转到指定行
if (condition_flag)
{
pos += 5;
int num = 0;
while (sentence[line_now][pos] != '\0')
{
num = num * 10 + sentence[line_now][pos] - '0';
pos++;
}
line_now = num;
}
// 判断句错误,则执行下一行
else
line_now++;
}
// PRINT 语句
else if (sentence[line_now][0] == 'P' && sentence[line_now][1] == 'R' && sentence[line_now][2] == 'I' && sentence[line_now][3] == 'N' && sentence[line_now][4] == 'T' && sentence[line_now][5] == ' ')
{
int pos = 6, i = 0, value1 = 0;
char var1[MAX_VAR_LENGTH];
memset(var1, 0, sizeof(var1));
// 获取变量名
while (sentence[line_now][pos] != '\0')
{
var1[i] = sentence[line_now][pos];
i++;
pos++;
}
// 根据变量名找到它对应的值大小
for (i = 0; i < var_num; i++)
{
// 找到相同的变量名,strcmp返回值为0
if (strcmp(var[i], var1) == 0)
{
value1 = value[i];
break;
}
}
printf("%d ", value1);
line_now++;
}
// = 赋值语句
else
{
int pos = 0, i = 0, op, index = 0, value2 = 0, value3 = 0;
char var1[MAX_VAR_LENGTH], var2[MAX_VAR_LENGTH], var3[MAX_VAR_LENGTH];
memset(var1, 0, sizeof(var1));
memset(var2, 0, sizeof(var2));
memset(var3, 0, sizeof(var3));
// 获取第一个变量名
while (sentence[line_now][pos] != ' ')
{
var1[i] = sentence[line_now][pos];
i++;
pos++;
}
pos = pos + 3;
// 获取第二个变量名
i = 0;
while (sentence[line_now][pos] != ' ')
{
var2[i] = sentence[line_now][pos];
i++;
pos++;
}
pos++;
// 获取运算元
if (sentence[line_now][pos] == '+' && sentence[line_now][pos + 1] == ' ')
{
op = 0;
pos += 1;
}
else if (sentence[line_now][pos] == '-' && sentence[line_now][pos + 1] == ' ')
{
op = 1;
pos += 1;
}
else if (sentence[line_now][pos] == '*' && sentence[line_now][pos + 1] == ' ')
{
op = 2;
pos += 1;
}
else if (sentence[line_now][pos] == '/' && sentence[line_now][pos + 1] == ' ')
{
op = 3;
pos += 1;
}
else if (sentence[line_now][pos] == '%' && sentence[line_now][pos + 1] == ' ')
{
op = 4;
pos += 1;
}
pos++;
// 获取第三个变量名
i = 0;
while (sentence[line_now][pos] != '\0')
{
var3[i] = sentence[line_now][pos];
i++;
pos++;
}
// 根据第二个变量名找到它对应的值大小
for (i = 0; i < var_num; i++)
{
// 找到相同的变量名,strcmp返回值为0
if (strcmp(var[i], var2) == 0)
{
value2 = value[i];
break;
}
}
// 根据第三个变量名找到它对应的值大小
for (i = 0; i < var_num; i++)
{
// 找到相同的变量名,strcmp返回值为0
if (strcmp(var[i], var3) == 0)
{
value3 = value[i];
break;
}
}
// 根据第一个变量名找到它对应的索引
for (i = 0; i < var_num; i++)
{
// 找到相同的变量名,strcmp返回值为0
if (strcmp(var[i], var1) == 0)
{
index = i;
break;
}
}
// 根据后两个变量的值和运算元来看给第一个变量赋值
switch (op)
{
case 0:
value[index] = value2 + value3;
break;
case 1:
value[index] = value2 - value3;
break;
case 2:
value[index] = value2 * value3;
break;
case 3:
value[index] = value2 / value3;
break;
case 4:
value[index] = value2 % value3;
break;
default:
break;
}
line_now++;
}
}
system("pause");
return 0;
}