初阶:
作业标题(c语言 循环)
乘法口诀表
作业内容
在屏幕上输出9*9乘法口诀表
int main()
{
int i = 0;
//行
for (i = 1; i <= 9; i++)
{
//每一行的打印
int j = 0;
for (j = 1; j <= i; j++)
{
printf("%d*%d=%-2d ", i, j, i * j);
}
printf("\n");
}
return 0;
}
-2d是左对齐,右边空着,2d右对齐,左边空着。
三个图片相比较,第一个有点凌乱,左对齐相对于好看一点。
另一种写法:
int main()
{
int i = 0;
//行
for (i = 1; i <= 9; i++)
{
//每一行的打印
int j = 0;
for (j = 1; j <= i; j++)
{
printf("%d*%d=%d\t", i, j, i * j);
}
printf("\n");
}
return 0;
}
\t 是水平制表符
\t 一般是4个空格(把要打印的算上,一共隔开4个字符)
作业标题(658)
求最大值
作业内容
求10 个整数中最大值
int main()
{
int arr[10] = { 0 };
/输入
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
scanf("%d", &arr[i]);
}
/求最大值
int max = arr[0];/假设第一个值就是最大值(如果这里int max =0的话,你输入负值(如-1,-2...)则
结果是0,因为max=0,没有一个数比0大,这里放arr[0],假设第一个值就是最大值)
for (i = 1; i < sz; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
//输出
printf("%d\n", max);
return 0;
}
作业内容(c语言 循环作业)
分数求和
计算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值,打印出结果
假如把这个做成全加:
int main()
{
int i=0;
int sum=0;
for(i=1;i<=100;i++)
{
sum+=1/i;
}
printf("%d\n",sum);
return 0;
}
如上代码的结果是1,为什么呢?
因为1/1是1,1/2是0.5,商0余1,依次往后类推全是0.几,最后加了一堆0,就是1,而我们这里想得到0.5,0.3这样的值,要得到小数。而除法有整数除法,有小数除法,要得到小数除法,除号的两端至少有一个浮点数,才执行浮点数除法
int main()
{
int i=0;
double sum=0;
for(i=1;i<=100;i++)
{
sum+=1.0/i;
}
printf("%d\n",sum);
return 0;
}
加减交替:
int main()
{
int i = 0;
double sum = 0.0;
int flag = 1;
for (i = 1; i <= 100; i++)
{
sum += flag * 1.0 / i;
flag = -flag;
}
printf("%lf\n", sum);
return 0;
}
这里第一个1/1执行完之后是1,接下来的数执行flag = -flag
这个flag第一趟是1,执行完sum+=那个表达式之后,flag = -flag,flag就变成-1,然后第二趟循环一执行,flag是-1,把它变成-flag,就成了1了,以此类推
另一种做法:
int main()
{
int i = 0;
double sum = 0.0;
int flag = 1;
for (i = 1; i <= 100; i++)
{
if (i % 2 == 1)
sum += flag * (1.0 / i);
else
sum -= flag * (1.0 / i);
}
printf("%lf\n", sum);
return 0;
}
作业标题(c语言 循环)
数9的个数
作业内容
编写程序数一下 1到 100 的所有整数中出现多少个数字9
思路:
要么个位出现9,要么十位出现9,如下:
9 19 29 39 49 59 69 79 89 99
90 91 92 93 94 95 96 97 98 99
int main()
{
int i = 0;
int count = 0;
for (i = 1; i <= 100; i++)
{
if (i % 10 == 9)//个位是9
count++;
if (i / 10 == 9)//十位为9
count++;
}
printf("%d\n", count);
return 0;
}
描述(c语言 循环)
小乐乐最近接触了求和符号Σ,他想计算
的结果。但是小乐乐很笨,请你帮助他解答。
输入描述:
输入一个正整数n (1 ≤ n ≤ 109)
输出描述:
输出一个值,为求和结果。
示例1
输入:1
输出:1
示例2
输入:10
输出:55
int main()
{
int n = 0;
scanf("%d", &n);
int i = 0;
int sum = 0;
for (i = 1; i <= n; i++)
{
sum += i;
}
printf("%lld\n", sum);
return 0;
}
这里会出现报错数字太大放不下,所以我们放个更大的值long long
int main()
{
long long n = 0;
scanf("%d", &n);
int i = 0;
long long sum = 0;
for (i = 1; i <= n; i++)
{
sum += i;
}
printf("%lld\n", sum);
return 0;
}
这是一种做法,我们知道,数学里面有等差数列求和
1 2 3 4 5 6 7......n 等差数列
(首项+尾项)*项数/2
像上面这个公式:(1+n)*n/2
int main()
{
long long n = 0;
scanf("%d", &n);
int i = 0;
long long sum = 0;
sum=(1+n)*n/2;
printf("%lld\n", sum);
return 0;
}
描述
小乐乐获得4个最大数,请帮他编程找到最大的数。
输入描述:
一行,4个整数,用空格分开。
输出描述:
一行,一个整数,为输入的4个整数中最大的整数。
示例1
输入:5 8 2 5
输出:8
int main() {
int arr[4] = {0};
int i = 0;
for(i=0; i<4; i++)
{
scanf("%d", &arr[i]);
}
/假设第一个值就是最大值
int max = arr[0];
for(i=1; i<4; i++)
{
if(arr[i]>max)
max = arr[i];
}
printf("%d\n", max);
return 0;
}
#include <limits.h>
int main() {
int arr[4] = {0};
int i = 0;
int max = INT_MIN;/假设最大值就是整型变量的最小值(每获取一个值,跟max比较一下,如果大于
max,交换)
for(i=0; i<4; i++)
{
scanf("%d", &arr[i]);
if(arr[i]>max)
max = arr[i];
}
printf("%d\n", max);
return 0;
}
描述
KiKi想判断输入的字符是不是字母,请帮他编程实现。
输入描述:
多组输入,每一行输入一个字符。
输出描述:
针对每组输入,输出单独占一行,判断输入字符是否为字母,输出内容详见输出样例。
示例1
输入:
A 6
输出:
A is an alphabet. 6 is not an alphabet.
scanf写法:
int main() {
char ch = 0;
while(scanf("%c", &ch) == 1)
{
if((ch>='a' && ch<='z') || (ch>='A' && ch<='Z') )
{
printf("%c is an alphabet.\n", ch);
}
else {
printf("%c is not an alphabet.\n", ch);
}
getchar();//处理\n
}
return 0;
}
int main() {
int ch = 0;
while((ch = getchar()) != EOF)
{
if((ch>='a' && ch<='z') || (ch>='A' && ch<='Z') )
{
printf("%c is an alphabet.\n", ch);
}
else {
printf("%c is not an alphabet.\n", ch);
}
getchar();//处理\n
}
return 0;
}
判断是不是字符有一个函数isalpha(),它是专门用来判断字符的,这个函数如果是字符返回一个整形,不是字符返回0,如下:
int main()
{
int ch = 0;
while((ch = getchar()) != EOF)
{
if(isalpha(ch))
{
printf("%c is an alphabet.\n", ch);
}
else {
printf("%c is not an alphabet.\n", ch);
}
getchar();//处理\n
}
return 0;
}
描述
KiKi非常喜欢网购,在一家店铺他看中了一件衣服,他了解到,如果今天是“双11”(11月11日)则这件衣服打7折,“双12” (12月12日)则这件衣服打8折,如果有优惠券可以额外减50元(优惠券只能在双11或双12使用),求KiKi最终所花的钱数。
数据范围:衣服价格满足 1 \le val \le 100000 \1≤val≤100000
输入描述:
一行,四个数字,第一个数表示小明看中的衣服价格,第二和第三个整数分别表示当天的月份、当天的日期、第四个整数表示是否有优惠券(有优惠券用1表示,无优惠券用0表示)。 注:输入日期保证只有“双11”和“双12”。
输出描述:
一行,小明实际花的钱数(保留两位小数)。(提示:不要指望商家倒找你钱)
示例1
输入:1000.0 11 11 1
输出:650.00
示例2
输入:999.8 12 12 0
输出:799.84
复制
示例3
输入:66.6 11 11 1
输出:0.00
int main()
{
float p = 0.0f;
int m = 0;
int d = 0;
int flag = 0;
scanf("%f %d %d %d", &p, &m, &d, &flag);
if (m == 11 && d == 11)
p = p * 0.7 - flag * 50;
else if (m == 12 && d == 12)
p = p * 0.8 - flag * 50;
if (p < 0.0)
p = 0.0;
printf("%.2f\n", p);
return 0;
}
作业标题(c语言 函数)
乘法口诀表
作业内容
实现一个函数,打印乘法口诀表,口诀表的行数和列数自己指定
如:输入9,输出9*9口诀表,输出12,输出12*12的乘法口诀表。
void print_table(int n)
{
int i = 0;
for (i = 1; i <= n; i++)
{
int j = 0;
for (j = 1; j <= i; j++)
{
printf("%-2d*%-2d=%-3d ", i, j, i * j);
}
printf("\n");
}
}
int main()
{
int n = 0;
scanf("%d", &n);
print_table(n);
return 0;
}
作业标题(C语言 函数)
根据下面递归函数:调用函数Fun(2),返回值是多少( )
int Fun(int n)
{
if(n==5)
return 2;
else
return 2*Fun(n+1);
}理解如下:
首先,给了Fun(2),2不等于5, Fun(2)推成了2*Fun(3),3不等于5,推成2*Fun(4),4不等于5,推成2*Fun(5),5=5,return 2,4个2相乘为16.
作业标题(c语言 函数)
递归实现n的k次方
作业内容
编写一个函数实现n的k次方,使用递归实现。
思路:
非递归:
int main()
{
int n = 0;
int k = 0;
scanf("%d %d", &n, &k);
double num =pow(n, k);
printf("%lf\n", num);
return 0;
}
递归:
double Pow(int n, int k)
{
if (k == 0)
return 1;
else if (k > 0)
return n * Pow(n, k - 1);
else
return 1.0 / Pow(n, -k);
}
int main()
{
int n = 0;
int k = 0;
scanf("%d %d", &n, &k);
double num =pow(n, k);
printf("%lf\n", num);
return 0;
}
作业标题(c语言 函数)
计算一个数的每位之和(递归实现)
作业内容
写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和
例如,调用DigitSum(1729),则应该返回1+7+2+9,它的和是19
输入:1729,输出:19
思路:(非负整数是unsigned)
DigitSum(1729)
DigitSum(172) + 9
DigitSum(17) 2 + 9
DigitSum(1) + 7 + 2 + 9
int DigitSum(int n)
{
if (n <= 9) 意思n是一位数,返回他自己
return n;
else
return DigitSum(n / 10) + n % 10;
}
int main()
{
unsigned int num = 0;
scanf("%d", &num);
int ret = DigitSum(num);
printf("%d\n", ret);
return 0;
}
作业标题(684)
字符串逆序(递归实现)
作业内容
编写一个函数 reverse_string(char * string)(递归实现)
实现:将参数字符串中的字符反向排列,不是逆序打印。
要求:不能使用C函数库中的字符串操作函数。
比如:
char arr[] = "abcdef"; 逆序之后数组的内容变成:fedcba
思路:
1.先将a和f逆序,加上剩下bcde,
2.逆序b和e,加上剩下cd
3.逆序c和d,加上空" "
非递归:
1. 假设不考虑递归
2. 直接使用库函数
int main()
{
char arr[] = "abcdef";
int left = 0;
int right = strlen(arr) - 1;
while (left <= right)
{
char tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
printf("%s", arr);
return 0;
}
这里使用了库函数,但是不能用
void reverse_string(char* s)
{
int len = strlen(s);
char tmp = s[0]; //s[0]第一个元素
s[0] = s[len - 1]; //s[0]存放f
s[len - 1] = '\0'; //只有这样才能逆序bcde,如果不是\0,无法逆序
if (strlen(s + 1) >= 2)
reverse_string(s + 1); //s是a,s+1是b
s[len - 1] = tmp;
}
int main()
{
char arr[] = "abcdefg";
reverse_string(arr);
printf("%s\n", arr);
return 0;
}
递归:
int my_strlen(char* s)
{
int count = 0;
while (*s != '\0')
{
count++;
s++;
}
return count;
}
void reverse_string(char* s)
{
if (*s == '\0') 指如果是空字符串,直接返回
return;
int len = my_strlen(s);
char tmp = s[0];
s[0] = s[len - 1];
s[len - 1] = '\0';
if (my_strlen(s + 1) >= 2)
reverse_string(s + 1);
s[len - 1] = tmp;
}
int main()
{
char arr[] = "abcdefg";
reverse_string(arr);
printf("%s\n", arr);
return 0;
}
但是,这里最简单的方法还是第一种。这个题不太适合用递归的方法。
作业内容(数组作业)
【一维数组】交换数组
将数组A中的内容和数组B中的内容进行交换。(数组一样大)
第一种情况:
int main()
{
int arr1[5] = { 1,2,3,4,5};
int arr2[5] = { 0,9,6,8,7};
int i = 0;
for (i = 0; i < 5; i++)
{
int tmp = arr1[i];
arr1[i] = arr2[i];
arr2[i] = tmp;
}
for (i = 0; i < 5; i++)
{
printf("%d ", arr1[i]);
}
printf("\n");
for (i = 0; i < 5; i++)
{
printf("%d ", arr2[i]);
}
printf("\n");
return 0;
}
注意:
for (i = 0; i < 5; i++)
{
int tmp = arr1[i];
arr1[i] = arr2[i];
arr2[i] = tmp;
}
要把这段代码放到前面,才能交换,放到后面不会交换
第二种情况:
int main()
{
int arr1[5] = { 1,2,3,4,5};
int arr2[5] = { 0,9,6,8,7};
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%d ", arr1[i]);
}
printf("\n");
for (i = 0; i < 5; i++)
{
printf("%d ", arr2[i]);
}
printf("\n");
for (i = 0; i < 5; i++)
{
int tmp = arr1[i];
arr1[i] = arr2[i];
arr2[i] = tmp;
}
return 0;
}
第一种情况结果如下图:
第二种情况结果如下图:
作业内容(数组)
使用函数实现数组操作
创建一个整形数组,完成对数组的操作
- 实现函数init() 初始化数组为全0
- 实现print() 打印数组的每个元素
- 实现reverse() 函数完成数组元素的逆置。
要求:自己设计以上函数的参数,返回值。
void Init(int a[], int sz)
{
int i;
for (i = 0; i < sz; i++)
{
a[i] = 0;
}
}
void print(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d", arr[i]);
}
printf("\n");
}
void reverse(int a[], int sz)
{
int t = 0;
int left = 0;
int right = sz - 1;
while (left <= right)
{
t = a[left];
a[left] = a[right];
a[right] = t;
left++;
right--;
}
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
printf("原数组:\n");
print(arr, sz);
Init(arr, sz);
printf("初始化数组:\n");
print(arr, sz);
reverse(arr, sz);
printf("逆序数组:\n");
print(arr, sz);
return 0;
}
上面的代码看不到显著的效果,接下来将代码顺序调整一下,看效果:
void print(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
void reverse(int arr[], int sz)
{
int left = 0;
int right = sz - 1;
while (left <right) //left < right说明还有元素逆序,left =right说明中间还有一个元素,不需要逆序
{
int tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
}
void init(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
arr[i] = 0;
}
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
print(arr, sz);
reverse(arr, sz);
print(arr, sz);
init(arr, sz);
print(arr, sz);
return 0;
}
作业标题(c语言 操作符)
统计二进制中1的个数
作业内容
写一个函数返回参数二进制中 1 的个数。
比如: 15 0000 1111 4 个 1
思路:
回顾课程,我们知道十进制的每一位可通过模10除10等到他的每一位,其实二进制也是一样的,二进制可通过模2除2得到他的每一位。
比如15,二进制位:00001111
15%2=1 这个1是最低位1,然后15/2——>7——> 111(7)
7%2商3余1,这个1是最低位的二个1 7/2——>3——>11(3)
依次类推
int number_of_1(int m)
{
/这里如果m变成0,他的二进制每一位都打印完了,m如果不为0,他的二进制序列里面还有1
int count = 0;
while (m)/如果m为0,循环就不进去
{
if (m % 2 == 1)
count++;
m /= 2;
}
return count;/当m为0,count是1的个数
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = number_of_1(n);
printf("%d\n", ret);
return 0;
}
这里当我们输入15,结果为4,答案是正确的,当时当我们输入-1,他打印0,但是我们都知道,-1的补码是32个1,那到底哪里出现问题了呢?
原因:
如果while (m)中m为-1,,-1%2肯定等于1,count++,-1/2不够商,商0,当0循环时进不了循环,所以返回0
那怎么解决这个问题呢?
因为-1里面确实存的是32个1,但是当我们把-1传过去,把他当成无符号数,-1就变成了数字,没有符号位,把-1直接当成一个非常大的正数,那他的每一位都是有效的,所以代码如下:
int number_of_1(unsigned int m)
{
int count = 0;
while (m)
{
if (m % 2 == 1)
count++;
m /= 2;
}
return count;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = number_of_1(n);
printf("%d\n", ret);
return 0;
}
另一种解决问题(不把他写成unsigened的形式):
int number_of_1(unsigned int m)
{
int count = 0;
int i = 0;
for (i = 0; i < 32; i++)
{
if (((m >> i) & 1) == 1)
count++;
}
return count;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = number_of_1(n);
printf("%d\n", ret);
return 0;
}
但是上面这个代码不管有几个1,都会循环32次,效率很低,那我们再来改进一下:
n&(n-1) 这个表达式会让n的二进制中最右边的1就消失了(就是说这个表达式执行依次去掉一个1,执行一次去掉一个1,他执行几次去掉几个1,直到变成0)
假如1110 14——>1110
n————>1110
n-1————>1101
n&(n-1)————>1100 把1100这个结果再放到n里面
n————>1100
n-1————>1011
n&(n-1)————>1000 把1000这个结果再放到n里面
n————>1000
n-1————>0111
n&(n-1)————>0000 把0000这个结果再放到n里面
看代码:
int number_of_1(unsigned int m)
{
int count = 0;
while (m)
{
m = m & (m - 1);
count++;
}
return count;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = number_of_1(n);
printf("%d\n", ret);
return 0;
}
拓展:
判断一个数字是不是2的幂次方
比如:8——>2^3
我们发现,2的幂次方这种里面二进制序列只有一个1,比如:2^0-->1,2^1-->10,2^3-->100...
所以当n&(n-1)等于0就说明他是2的幂次方
作业标题(c语言 操作符)
打印整数二进制的奇数位和偶数位
作业内容
获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列
思路:
要先确定他的二进制序列中那个奇数位,那个偶数位(就是说看最低位是奇数偶数)
int main()
{
int n = 0;
scanf("%d", &n);
int i = 0;
//奇数:30 28 26...
for (i = 30; i >= 0; i -= 2)
{
printf("%d ", (n >> i) & 1);
}
printf("\n");
//偶数
for (i = 31; i >= 1; i -= 2)
{
printf("%d ", (n >> i) & 1);
}
return 0;
}
另一种:
作业标题(c语言 操作符)
求两个数二进制中不同位的个数
作业内容
编程实现:两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同?
输入例子:
1999 2299
输出例子:7
int number_of_1(unsigned int m)
{
int count = 0;
while (m)
{
m = m & (m - 1);
count++;
}
return count;
}
int main()
{
int n = 0;
int m = 0;
scanf("%d %d", &n,&m);
int ret = number_of_1(m^n);
printf("%d\n", ret);
return 0;
}
另一种方法:
作业标题(c语言 操作符)
【一维数组】BC100-有序序列合并
描述
输入两个升序排列的序列,将两个序列合并为一个有序序列并输出。
数据范围: 1 \le n, m \le 1000 \1≤n,m≤1000 , 序列中的值满足 0 \le val \le 30000 \0≤val≤30000
输入描述:
输入包含三行,
第一行包含两个正整数n, m,用空格分隔。n表示第二行第一个升序序列中数字的个数,m表示第三行第二个升序序列中数字的个数。
第二行包含n个整数,用空格分隔。
第三行包含m个整数,用空格分隔。
输出描述:
输出为一行,输出长度为n+m的升序序列,即长度为n的升序序列和长度为m的升序序列中的元素重新进行升序序列排列合并。
输入:5 6
1 3 7 9 22
2 8 10 17 33 44
输出:
1 2 3 7 8 9 10 17 22 33 44
/合并两个有序数组并保持有序性
int main()
{
int a[5] = { 1,3,5,7,9 };
int b[5] = { 0,2,4,6,8 };
int c[10];
int i, j, itm;
/将两个有序数列对接,合并成一个无序数列
for (i = 0; i < 5; i++)
{
c[i] = a[i];
}
for (j = 0; j < 5; j++, i++)
{
c[i] = b[j];
}
/选择排序法,将无序数列c从小到大排序
for (i = 0; i < 10; i++)
{
for (j = 1; i + j < 10; j++)
{
if (c[i] > c[i + j])
{
itm = c[i]; c[i] = c[i + j]; c[i + j] = itm;
}
}
}
for (i = 0; i < 10; i++)
{
printf("%d ", c[i]);
}
}
这个代码只能是相同元素个数合并
int main() {
int n = 0;
int m = 0;
scanf("%d %d", &n, &m);
//变长数组
int arr1[1000];
int arr2[1000];
int i = 0;
//第一行数据
for (i = 0; i < n; i++)
{
scanf("%d", &arr1[i]);
}
//第二行数据
for (i = 0; i < m; i++)
{
scanf("%d", &arr2[i]);
}
//合并
int arr3[2000];
i = 0;
int j = 0;
int k = 0;
while (i < n && j < m)
{
if (arr1[i] < arr2[j])
{
arr3[k++] = arr1[i++];
}
else
{
arr3[k++] = arr2[j++];
}
}
if (i == n)
{
//arr1遍历完了,需要将arr2中剩余的元素全部放在arr3中
while (j < m)
{
arr3[k++] = arr2[j++];
}
}
else
{
//arr2遍历完了,需要将arr1中剩余的元素全部放在arr3中
while (i < n)
{
arr3[k++] = arr1[i++];
}
}
//输出
for (i = 0; i < n + m; i++)
{
printf("%d ", arr3[i]);
}
return 0;
}
优化:
int main() {
int n = 0;
int m = 0;
scanf("%d %d", &n, &m);
//变长数组
int arr1[1000];
int arr2[1000];
int i = 0;
//第一行数据
for (i = 0; i < n; i++)
{
scanf("%d", &arr1[i]);
}
//第二行数据
for (i = 0; i < m; i++)
{
scanf("%d", &arr2[i]);
}
//合并
int arr3[2000];
i = 0;
int j = 0;
int k = 0;
while (i < n && j < m)
{
if (arr1[i] < arr2[j])
{
printf("%d ", arr1[i++]);//那个小打印那个
}
else
{
printf("%d ", arr1[j++]);//那个小打印那个
}
}
if (i == n)
{
//arr1遍历完了,需要将arr2中剩余的元素全部放在arr3中
while (j < m)
{
printf("%d ", arr2[j++]);
}
}
else
{
//arr2遍历完了,需要将arr1中剩余的元素全部放在arr3中
while (i < n)
{
printf("%d ", arr1[i++]);
}
}
return 0;
}
作业标题(c语言 操作符)
BC96-有序序列判断
描述
输入一个整数序列,判断是否是有序序列,有序,指序列中的整数从小到大排序或者从大到小排序(相同元素也视为有序)。
数据范围: 3 \le n \le 50 \3≤n≤50 序列中的值都满足 1 \le val \le 100 \1≤val≤100
输入描述:
第一行输入一个整数N(3≤N≤50)。
第二行输入N个整数,用空格分隔N个整数。
输出描述:
输出为一行,如果序列有序输出sorted,否则输出unsorted。
示例1
输入:5
1 6 9 22 30
输出:sorted
示例2
输入:5
3 4 7 2 10
输出:unsorted
示例3
输入:5 1 1 1 1 1
输出:sorted
int main()
{
int n = 0;
scanf("%d", &n);
int arr[50] = { 0 };
//输入数据
int i = 0;
for (i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
/判断是否有序
/有两种情况,1.有序分为升序(元素之间都是小于关系)降序(都是大于关系),2.无序(小于大于关
系都有)
int flag1 = 0;/相邻两个元素满足升序关系
int flag2 = 0;/相邻两个元素满足降序关系
for (i = 0; i < n - 1; i++)/如果是n个元素比较,比较n-1次
{
if (arr[i] < arr[i + 1])
flag1 = 1;
else if (arr[i] > arr[i + 1])
flag2 = 1;
}
if (flag1 + flag2 == 2)/两个都满足
printf("unsorted\n");
else
printf("sorted");
return 0;
}
优化:
这里读第一个不比较,读第二个比较,一对一对比(一边输入一边判断)
int main()
{
int n = 0;
scanf("%d", &n);
int arr[50] = { 0 };
//输入数据
int i = 0;
//判断是否有序
int flag1 = 0;
int flag2 = 0;
for (i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
if (i >= 1)/大于等于1说明有两个元素开始比较
{
if (arr[i] < arr[i - 1])/他和他的前一个比较
flag1 = 1;
else if (arr[i] > arr[i - 1])
flag2 = 1;
}
}
if (flag1 + flag2 == 2)
printf("unsorted\n");
else
printf("sorted");
return 0;
}
思路:读一个不比较,当第二个读进来之后在比较
作业标题(c语言 操作符)
BC54-获得月份天数
描述
KiKi想获得某年某月有多少天,请帮他编程实现。输入年份和月份,计算这一年这个月有多少天。
输入描述:
多组输入,一行有两个整数,分别表示年份和月份,用空格分隔。
输出描述:
针对每组输入,输出为一行,一个整数,表示这一年这个月有多少天。
示例1
输入:2008 2
输出:29
多组输入:
1 2 3 4 5 6 7 8 9 10 11 12
/平年:31,28,31,30,31,30,31,31,30,31,30,31(一月大,31天,二月小,28...)
/闰年: 29
(闰年只有二月29天)
int get_days_of_month(int y, int m)
{
int d = 0;
switch(m)
{
/31天
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
d = 31;
break;
/30天
case 4:
case 6:
case 9:
case 11:
d = 30;
break;
/28 29
case 2:
{
d = 28;
if((y%4==0&& y%100!=0) || (y%400==0))/判断是不是闰年,是要+1
d += 1;
}
}
return d;
}
int main()
{
int y = 0;/年
int m = 0;/月
while (scanf("%d %d", &y, &m) == 2)
{
int d = get_days_of_month(y, m);
printf("%d\n", d);
}
return 0;
}
int get_days_of_month(int y, int m)
{
int d = 0;
int days[] = { 0, 31,28,31,30,31,30,31,31,30,31,30,31 };
d = days[m];
if (((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0)) && m == 2)/判断是不是闰年的2月
d += 1;
return d;
}
int main()
{
int y = 0;
int m = 0;
while (scanf("%d %d", &y, &m) == 2)
{
int d = get_days_of_month(y, m);
printf("%d\n", d);
}
return 0;
}
作业标题(c语言 指针)
使用指针打印数组内容
作业内容
写一个函数打印arr数组的内容,不使用数组下标,使用指针。
arr是一个整形一维数组。
1.
int main()
{
float arr[] = { 3.14f, 99.9f ,66.5f, 0.0f};
int i = 0;
float* p = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
printf("%.2f ", *p);//想打印两位就用.2f
p++;
}
return 0;
}
2.
int main()
{
float arr[] = { 3.14f, 99.9f ,66.5f, 0.0f };
int i = 0;
float* p = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
printf("%.2f ", *(p+i));
}
return 0;
}
指针大小的比较:
3.
int main()
{
float arr[] = { 3.14f, 99.9f ,66.5f, 0.0f };
int i = 0;
float* p = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
float* q = arr + sz;
while (p < q)
{
printf("%.2f ", *p++);
}
return 0;
}
题目:使用一个函数:
4.
void print(float* p, int sz)
{
float* q = p + sz;
while (p < q)
{
printf("%.2f ", *p++);
}
}
int main()
{
float arr[] = { 3.14f, 99.9f ,66.5f, 0.0f };
int i = 0;
float* p = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
print(arr, sz);
return 0;
}
1.
2.
3.
4.
作业标题(c语言 指针)
字符串逆序
作业内容
写一个函数,可以逆序一个字符串的内容。
将一个字符串str的内容颠倒过来,并输出。
数据范围:1≤len(str)≤10000 1 \le len(str) \le 10000\ 1≤len(str)≤10000
输入描述:输入一个字符串,可以有空格
输出描述:输出逆序的字符串
示例1
输入:I am a student
输出:tneduts a ma I
示例2
输入:nowcoder
输出:redocwon
int main() {
char arr[10001] = { 0 };
gets(arr);
int len = strlen(arr);
char* left = arr;
char* right = arr + len - 1;
while (left < right)
{
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
printf("%s\n", arr);
return 0;
}
作业标题(c语言 指针)
打印菱形
作业内容
用C语言在屏幕上输出以下图案:
int main()
{
int line = 0;
scanf("%d", &line);//7
/上
int i = 0;
for (i = 0; i < line; i++)
{
/每次进来打印一行
/1.先打印空格
int j = 0;
for (j = 0; j < line - 1 - i; j++) /line-1:上半部分是7行减去满的一行,要让他变化,再减i(7-1,7-2...7-7)
{
printf(" ");
}
/2.再打印*
for (j = 0; j < 2 * i + 1; j++) /2*i+1:2*0+1=1,2*1+1=3...
{
printf("*");
}
printf("\n");
}
/下
for (i = 0; i < line-1; i++)
{
int j = 0;
for (j = 0; j <= i; j++)
{
printf(" ");
}
/打印*
for (j = 0; j < 2*(line-1-i)-1; j++)
{
printf("*");
}
printf("\n");
}
return 0;
}
作业标题(c语言 指针)
打印水仙花数
作业内容
求出0~100000之间的所有“水仙花数”并输出。
“水仙花数”是指一个n位数,其各位数字的n次方之和确好等于该数本身,如:153=1^3+5^3+3^3,则153是一个“水仙花数”。
自幂数:
数学用语:
如果在一个固定的进制中,一个n位自然数等于自身各个数位上数字的n次幂之和,则称此数为自幂数。
例如:在十进制中,153是一个三位数,各个数位的3次幂之和为1^3+5^3+3^3=153,所以153是十进制中的自幂数。
在n进制中,所有小于n的正整数都为自幂数,比如2进制中1是自幂数,3进制中1和2都是自幂数,4进制中1,2和3都是自幂数......
各种自幂数的名称
一位自幂数:独身数
两位自幂数:没有
三位自幂数:水仙花数
四位自幂数:四叶玫瑰数
五位自幂数:五角星数
六位自幂数:六合数
七位自幂数:北斗七星数
八位自幂数:八仙数
九位自幂数:九九重阳数
十位自幂数:十全十美数
理解:
“水仙花数"就是自幂数
自幂数就是,假设有个数m,m他是n位数
m的每一位的n次方之后等于m
例如:153是3位数
自幂数就是:1^3 + 5^3 + 3^3 == 153
#include <math.h>
int main()
{
int i = 0;
for (i = 0; i <= 100000; i++)
{
/判断i是否是自幂数就行
/ 怎么判断呢?1.首先要知道几位数n,2.然后计算n次方之和
/1. 计算i的位数 - n
int n = 1;
int tmp = i;
while (tmp /= 10) /除10去掉一位
{
n++;
}
/2. 求每一位的n次方之和
tmp = i;
int sum = 0;
while (tmp)
{
sum += pow(tmp % 10, n);/模10得到他的每一位
tmp /= 10;
}
/3. 判断
if (sum == i)
{
printf("%d ", i);
}
}
return 0;
}
作业标题(c语言 指针)
计算求和
作业内容
求Sn=a+aa+aaa+aaaa+aaaaa的前5项之和,其中a是一个数字,
例如:2+22+222+2222+22222
int main()
{
int a = 0;
int n = 0;
scanf("%d %d", &a, &n);//2 5
int i = 0;
int sum = 0;
int k = 0;
for (i = 0; i < n; i++)
{
k = k * 10 + a;/k=0,a=2,k*10+2=2, k=2
sum += k; /sum=2 就是每次算一项给他加上去,算一项给他加上去
}
printf("%d\n", sum);
return 0;
}
作业标题(c语言 指针)
喝汽水问题
作业内容
喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以多少汽水(编程实现)。
1.
int main()
{
int money = 0;
int total = 0;/能买多少瓶水
int empty = 0;/空瓶数
scanf("%d", &money);
total += money;
empty += money;/空瓶数等于money
while (empty >= 2)/置换
{
total += empty / 2;
empty = empty / 2 + empty%2;
}
printf("total = %d\n", total);
return 0;
}
2.
int main()
{
int money = 0;
int total = 0;/能买多少瓶水
int empty = 0;/空瓶数
scanf("%d", &money);
total += money;
empty += money;/空瓶数等于money
if (money > 0)
total = 2 * money - 1;
printf("total = %d\n", total);
return 0;
}
1.
2.
作业标题(c语 言 结构体Debug和Release的区别)
调整奇数偶数顺序
作业内容
调整数组使奇数全部都位于偶数前面。
题目:
输入一个整数数组,实现一个函数,
来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,
所有偶数位于数组的后半部分。
解释:
就是说,给一组数,奇数和偶数是交错的,
整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,所有偶数位于数组的后半部分(这里只是说奇数在前面,偶数在后面,并不知道有几个奇数几个偶数)。
1.
第一种这里要创建两个数组
比如:
第一个数组:1,2,3,4,5,6,7,8,9
第二个数组:1,3,5,7,9,2,4,6,8
2.双指针
假如给一组数据,前面找是奇数就不变,前面是偶数就放到后面去。后面找是偶数就不变,是奇数就放到前面去
例如:
1,2,3,4,5,6,7,8,9
1是奇数不管,往后走2偶数,9是奇数,,两个一交换,载往后走,3是奇数不管,8是偶数不管,往后走4是偶数,7是奇数,交换...
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9 };
int sz = sizeof(arr) / sizeof(arr[0]);
int l = 0;/左下标
int r = sz - 1;/右下标
while (l<r)
{
/从前向后找一个偶数
while ((l < r) && arr[l] % 2 == 1)/l不能加到超过r
{
l++;
}
/从后向前找一个奇数,找到奇数,要跟前面的偶数交换
while ((l < r) && arr[r] % 2 == 0)
{
r--;
}
if (l < r)
{
int tmp = arr[l];
arr[l] = arr[r];
arr[r] = tmp;
l++;
r--;
}
}
/打印
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
如果像下面这样写,假如数组里面放的全是奇数的时候,从前往后走的过程中,
l一直在++,这个++的过程中有可能就越界访问了
while ((arr[l] % 2 == 1)
{
l++;
}
所以要像如下这样写,要两个条件同时满足
while ((l < r) && arr[l] % 2 == 1)//l不能加到超过r
{
l++;
}
作业标题(c语言 实用调试 const修饰指针)
BC68-X形图案
作业内容:X形图案
描述
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的X形图案。
输入描述:
多组输入,一个整数(2~20),表示输出的行数,也表示组成“X”的反斜线和正斜线的长度。
输出描述:
针对每行输入,输出用“*”组成的X形图案。
int main()
{
int n = 0;
while (scanf("%d", &n) == 1)/只读一个数字,所以等于1
{
int i = 0;
int j = 0;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if (i == j || i + j == n - 1)/i + j == n - 1行和列加起来等于4或者i==j
printf("*");
else
printf(" ");
}
printf("\n");
}
}
return 0;
}
作业标题(c语言 实用调试 const修饰指针)
BC60-带空格直角三角形图案
作业内容:带空格直角三角形图案
描述
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的带空格直角三角形图案。
输入描述:
多组输入,一个整数(2~20),表示直角三角形直角边的长度,即“*”的数量,也表示输出行数。
输出描述:
针对每行输入,输出用“*”组成的对应长度的直角三角形,每个“*”后面有一个空格。
int main()
{
int n = 0;
while (scanf("%d", &n) == 1)
{
int i = 0;
int j = 0;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if (i + j < n - 1)
printf(" ");
else
printf("* ");
}
printf("\n");
}
}
return 0;
}
进阶:
作业标题(c语言 数据在内存中的存储1)
猜名次
作业内容
5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:
A选手说:B第二,我第三;
B选手说:我第二,E第四;
C选手说:我第一,D第二;
D选手说:C最后,我第三;
E选手说:我第四,A第一;
比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。
思路:
每个人的名次有5种可能
怎么理解每位选手都说对了一半呢?
我们学过比较运算符,他的结果要么真要么假,真是0,假是1.像A选手说:B第二,我第三,这个就是(b == 2) + (a == 3) == 1,因为他说对了一半。(就是0+1=1或者1+0=1)
int main()
{
int a = 0;
int b = 0;
int c = 0;
int d = 0;
int e = 0;
for (a = 1; a <= 5; a++)
{
for (b = 1; b <= 5; b++)
{
for (c = 1; c <= 5; c++)
{
for (d = 1; d <= 5; d++)
{
for (e = 1; e <= 5; e++)
{
if (((b == 2) + (a == 3) == 1) &&
((b == 2) + (e == 4) == 1) &&
((c == 1) + (d == 2) == 1) &&
((c == 5) + (d == 3) == 1) &&
((e == 4) + (a == 1) == 1))
{
if(a*b*c*d*e == 120)
printf("a=%d b=%d c=%d d=%d e=%d\n", a, b, c, d, e);
}
}
}
}
}
}
return 0;
}
作业标题(c语言 数据在内存中的存储1)
猜凶手
作业内容
日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。
以下为4个嫌疑犯的供词:
A说:不是我。
B说:是C。
C说:是D。
D说:C在胡说
已知3个人说了真话,1个人说的是假话。
思路:
A B C D
假设凶手是A:假 假 假 假 已经两个为假,所以不是A
假设凶手是B:真 假 假 假 已经两个为假,所以不是B
假设凶手是C:真 真 假 真 凶手是C
假设凶手是D:真 假 真 假 已经两个为假,所以不是D
现在请根据这些信息,写一个程序来确定到底谁是凶手。
int main()
{
char killer = 0;
for (killer = 'a'; killer <= 'd'; killer++)
{
if ((killer!='a') + (killer=='c') + (killer=='d') + (killer!='d') == 3)
{
printf("%c\n", killer);
break;
}
}
}
作业标题(c语言 数据在内存中的存储1)
杨辉三角
作业内容
在屏幕上打印杨辉三角。
1
1 1
1 2 1
1 3 3 1
……
int main()
{
int arr[10][10] = { 0 };
int i = 0;
for (i = 0; i < 10; i++)
{
int j = 0;
for (j = 0; j <= i; j++)
{
if (i == j || j == 0)
arr[i][j] = 1;
if (i >= 2 && j >= 1)
{
arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
}
}
}
for (i = 0; i < 10; i++)
{
int j = 0;
for (j = 0; j <= i; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
return 0;
}