目录
[第六题sum = 21](#第六题sum = 21)
[第七题设字符型变量x的值是064,表达式"~ x ^ x << 2 & x"的值是()编辑](#第七题设字符型变量x的值是064,表达式“~ x ^ x << 2 & x”的值是()编辑)
[第八题变量void (*s[5])(int)表示意思为](#第八题变量void (*s[5])(int)表示意思为)
小蓝数点
此题要用到两个数学公式
1、三点间面积公式:s = |(x2 - x1) × (y3 - y2) - (y2 - y1) × (x3 - x2)| / 2
代码实现 :
s = x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2);
if (s < 0)
{
s = -s;
}
s = s / 2;
2、皮克定理:是一个计算点阵中顶点在格点上的多边形面积公式,具体为S=a+b÷2-1,其中a表示多边形内部的点数,b表示多边形落在格点边界上的点数,S表示多边形的面积。
代码实现:
n = s + 1 - count / 2;
接下来是解题思路:
-
变量声明:
-
x1, y1, x2, y2, x3, y3:这些变量用于存储三条线段的端点坐标。 s:存储三条线段的交点数量。 k1, k2, k3:存储线段的斜率。 count:存储三条线段之间交点的数量。(count = -6,而后每个点计算两次,故后面计算不用-1) t:用于计算交点坐标的临时变量。 n:最后输出结果。
-
求面积
-
对三个坐标进行排序,使得x1 <= x2 <= x3。这一步是为了简化后续的计算过程。
-
计算斜率k1、把x1和x2之间的整数点一一带入点斜式计算,判断y是否为整数,若为整数,则count++,注意斜率不存在的情况,此时直接计算两点间有几个点是整数点。
-
对于k2、k3重复上述操作。
-
最后,计算输出结果n = s - count / 2,并输出(此处不需要减一,因为减一的情况已经考虑过了)。
个人认为此方法的缺陷:代码中存在一些冗余,可能需要进行调整和优化以适应特定的需求,此算法也并非最优解,只是我个人能想出来的解。
int main(int argc, char* argv[])
{
double x1 = 0, y1 = 0;
double x2 = 0, y2 = 0;
double x3 = 0, y3 = 0;
double s = 0, k1 = 0, k2 = 0, k3 = 0;
double count = 0, t = 0;
/*double a = 0, b = 0, c = 0;*/
long long int n = 0;
scanf("%lf%lf", &x1, &y1);
scanf("%lf%lf", &x2, &y2);
scanf("%lf%lf", &x3, &y3);
s = x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2);
if (s < 0)
{
s = -s;
}
s = s / 2;
if (x1 > x2)
{
x1 = x1 + x2;
x2 = x1 - x2;
x1 = x1 - x2;
y1 = y1 + y2;
y2 = y1 - y2;
y1 = y1 - y2;
}
if (x2 > x3)
{
x3 = x3 + x2;
x2 = x3 - x2;
x3 = x3 - x2;
y3 = y3 + y2;
y2 = y3 - y2;
y3 = y3 - y2;
}
if (x1 > x3)
{
x3 = x3 + x1;
x1 = x3 - x1;
x3 = x3 - x1;
y3 = y3 + y1;
y1 = y3 - y1;
y3 = y3 - y1;
}
if (x1 != x2)
{
k1 = (y1 - y2) / (x1 - x2);
for (int i = x1 + 1; i < x2; i++)
{
t = y1 + k1 * (i - x1);
if (t - ceil(t) == 0)
{
count++;
}
t = 0;
}
}
else {
int m = y2 - y1;
if (m < 0)
{
m = -m;
}
count += m - 2;
}
if (x2 != x3)
{
k2 = (y2 - y3) / (x2 - x3);
for (int i = x2 + 1; i < x3; i++)
{
t = y2 + k2 * (i - x2);
if (t - ceil(t) == 0)
{
count++;
}
t = 0;
}
}
else {
int m = y3 - y2;
if (m < 0)
{
m = -m;
}
count += m - 2;
}
if (x1 != x3)
{
k3 = (y1 - y3) / (x1 - x3);
for (int i = x3; i > x1; i--)
{
t = y3 + k3 * (i - x3);
if (t - ceil(t) == 0)
{
count++;
}
t = 0;
}
}
else {
int m = y3 - y1;
if (m < 0)
{
m = -m;
}
count += m - 2;
}
n = s - count / 2;
printf("%lld", n);
return 0;
}
第一题程序的输出结果是?:
第一次循环:a = 1,b=1--->b小于20,if不成立,b=b+3, 此时b的值为4,
以此类推:
第八次循环:a = 8,b=1+3*7--->b大于20,if成立,循环break终止
最后打印a:8
第二题下面代码的执行结果是什么?:
switch的每个case之后如果没有加break语句,当前case执行结束后,会继续执行紧跟case中的语句。故最终执行default之后的语句
第三题下面代码的执行结果是什么?:
#include <stdio.h>
int main() {
int x = 3;
int y = 3;
switch (x % 2) { // x%2的结果为1,因此执行case1
case 1:
switch (y) // y是3,因此会执行case3,而case3不存在,那只能执行default
{
case 0:
printf("first");
case 1:
printf("second");
break;
default: printf("hello"); // 打印hello,打印完之后,内部switch结束,此时外部case1结束
} // 因为外部case1之后没有添加break语句,所以继续执行case2
case 2: // 打印third
printf("third"); // 外部switch结束
}
return 0;
}
同上,如果没有break,case语句会从上往下一直执行
第四题关于关系操作符说法错误的是?:
两个字符串是否相等不能使用==,应该使用strcmp函数
第五题对于下面代码段,y的值为?
此处有两个坑,
1、求的是y的值,而不是t
2、若||左边为真则不计算右边的代码
第六题sum = 21
-
a[3][3]={{3,5},{8,9},{12,35}};
-
二维数组没有初始化的值默认初始化为0,
-
即:a[3][3]={{3,5,0},{8,9,0},{12,35,0}};
-
sum = a[0][2]+a[1][1]+a[2][0] = 0+9+12 = 21。
第七题设字符型变量x的值是064,表达式"~ x ^ x << 2 & x"的值是()
-
x << 2: 这将x的二进制表示左移2位。由于x是字符型变量,其值为064(八进制),这在十进制中是52,二进制中是00110100。左移2位后,它变为11010000。
-
~x: 这是对x的按位取反。对于x = 00110100,取反后得到11001011。
-
~x ^ x: 这是上面得到的两个结果的异或操作。即11001011 XOR 00110100 = 11111111。
-
(~x ^ x) & x << 2: 这是上面得到的11111111与x << 2的结果(即11010000)的按位与操作。结果为11010000,即八进制的333。
-
最后八进制前置加上0,0333,选A
第八题变量void (*s[5])(int)表示意思为
-
先看主体:s[5] 这表示s是一个大小为5的数组。
-
*s:在数组前加上*表示数组的每个元素都是一个指针。
-
void (*)(int):这是一个函数指针的类型,它指向一个接受一个int参数并返回void的函数。
-
总结:该类题需先看主体是数组,函数,还是指针
今天就先到这了!!!
看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注!
你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信!!!
关注必回!!!