0%

喝汽水问题等

文章时效性提示

本文发布于 508 天前,部分信息可能已经改变,请注意甄别。

喝汽水问题

喝汽水,1瓶汽水1元,2个空瓶换一瓶汽水,给20元,可以喝多少汽水。

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
int main() {
    float Money = 20;
    int Cola = 0;
    for (; Money>=1; Money--) {
        Cola++;
        Money = Money + 0.5;
    }
    printf("%d\n",Cola);
    return 0;
}

调整数组使奇数全部位于偶数前面

调整数组使奇数全部位于偶数前面
使所有奇数位于数组前半部分,偶数位于后半部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
int main()
{
    int arr[] = {213,12312,3452,1236,764,221,1323,4532};
    int sz = sizeof(arr)/sizeof(arr[0]);
    int left = 0;
    int right = sz - 1;
    while (left<right) {
        if (arr[left] % 2 == 0 && arr[right] % 2 != 0)//左边是偶数,并且右边是奇数
        {
            int temp;
            temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
        }
                if (arr[left] % 2 != 0) {
                    left++;
                }
                if (arr[right] % 2 == 0) {
                    right--;
                }
    }
        for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++) {
            printf("%d ", arr[i]);
        }
        return 0;
}

1
2
3
4
5
6
7
8
9
#include <stdio.h>
int main() {
    unsigned char a = 200;
    unsigned char b = 100;
    unsigned char c = 0;
    c = a + b;
    printf("%d %d",a+b,c);
    return 0;
}

需要进行整型提升:
a的二进制:00000000 00000000 00000000 11001000
b的二进制:00000000 00000000 00000000 01100100
加起来结果:00000000 00000000 00000001 00101100
c是unsigned char 型,只取后8为,即00101100
所以c的十进制是44
直接打印a+b不需要取后8位,为300
打印的结果是300 44


在屏幕上打印杨辉三角

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>
int main() {
    int arr[10][10] = {0};
    int i = 0;
    arr[0][0] = 1;
    //计算
    for (i=1; i<10; i++)
    {
        int j = 0;
        for (j=0; j<=i; j++)
        {
            arr[i][j] = arr[i-1][j-1] + arr[i-1][j];
        }
    }
    //打印出来
    for (i=0; i<10; i++)
    {
        int a = 0;
        for (a=0; a<=i; a++)
        {
            printf("%d ",arr[i][a]);
        }
        printf("\n");
    }
    return 0;
}

猜凶手

发生谋杀案,凶手是4人中的一个。有三人说真话,一人说假话。
A:不是我
B:是C
C:是D
D:C在胡说
写程序确定谁是凶手

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
int main() {
    int killer = 0;
    for (killer = 'a'; killer<='d'; killer++) {
        if ((killer != 'a') + (killer == 'c') + (killer == 'd') + (killer != 'd') == 3) {
            printf("killer = %c\n",killer);
        }
    }
    return 0;
}

赛马问题

有36只马,六个跑道,没有计时器,请赛马确定36匹马的前三名。
请问最少赛几次?

  • 36匹马,分为6组,分别跑,+六次
  • 让第一次获得第一名的六只马跑,+1次
  • 让第二次获得第一名的组里的前三名、第二名组里的前2名、第三名跑,+1次
  • 一共需要8次

烧香问题

一种香,材质不均匀,但每根烧完刚好是1小时。
给2根香,确定15分钟的时间

  • 一根点燃两头,一根点燃一头
  • 第一根燃完即半小时,熄灭第二根
  • 第二根两头点燃,烧完刚好是15分钟

5名运动员参加比赛:
A:B第二,我第三
B:我第二,E第四
C:我第一,D第二
D:C最后,我第三
E:我第四,A第一
每人说对一半,确定名次。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
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)&&
                            (a*b*c*d*e==120))
                        {
                            printf("a = %d,b = %d,c = %d,d = %d,e = %d",a,b,c,d,e);
                        }
                    }
                }
            }
        }
    }
    return 0;
}

字符串左旋

实现一个函数,可以左旋字符串中的k个字符
例如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB

方法一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>
void Xuan(char* ch,int sz,int k)
{
    char temp[k-1];
    int i;
    //设置个中间变量,把要左旋的的保存到这里
    for (i=0; i<k; i++) {
        temp[i] = ch[i];
    }
    //把从k开始的字符往左边移,给temp留位置
    for (i=0; i<=sz-k; i++) {
        ch[i] = ch[k+i];
    }
    //把temp保存的值给ch后边
    for (i=0; i<k; i++) {
        ch[sz-k+1+i] = temp[i];
    }
}
int main() {
    char ch[] = "ABCDEFGH";
    int k = 3;//左旋的位数
    int i ;
    int sz = sizeof(ch)/sizeof(ch[0]) - 2;
    printf("sz = %d\n",sz);
    Xuan(ch,sz,k);
    for (i=0; i<=sz; i++) {
        printf("%c ",ch[i]);
    }
    return 0;
}

方法二:三步翻转法
例如一个字符串:abcdef
先分成两部分: ab cdef
把前后两部分倒序:bafedc
再全部反转:cdefab

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//三步翻转法
#include <stdio.h>
#include <string.h>
#include <assert.h>
void reverse(char* left,char* right)
{
    assert(left != NULL);
    assert(right != NULL);
    while (left<right) {
        char tmp = *left;
        *left = *right;
        *right = tmp;
        left++;
        right--;
    }
}
void left_move(char* arr,int k)
{
    assert(arr);
    int len = strlen(arr);
    assert(k<=len);
    reverse(arr,arr+k-1);//逆序左边
    reverse(arr+k,arr+len-1);//逆序右边
    reverse(arr,arr+len-1);//逆序整体
}

int main() {
    char arr[] = "abcdef";
    left_move(arr,2);
    printf("%s\n",arr);
    return 0;
}

写一个函数,判断一个字符串是否为另一个字符串旋转之后的字符串
例如:给定S1=AABCD和S2=BCDAA,返回1
给定S1=ABCD和S2=ACBD,返回0
AABCD左旋一个字符得到ABCDA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <stdio.h>
#include <string.h>
#include <assert.h>
void reverse(char* left,char* right)
{
    assert(left != NULL);
    assert(right != NULL);
    while (left<right) {
        char tmp = *left;
        *left = *right;
        *right = tmp;
        left++;
        right--;
    }
}

void left_move(char* arr,int k)
{
    assert(arr);
    int len = strlen(arr);
    assert(k<=len);
    reverse(arr,arr+k-1);//逆序左边
    reverse(arr+k,arr+len-1);//逆序右边
    reverse(arr,arr+len-1);//逆序整体
}

int is_left_move(char* s1,char*s2)
{
    int len = strlen(s1);
    int i = 0;
    for (i=0; i<len; i++) {
        left_move(s1, 1);
        int ret = strcmp(s1, s2);
        if (ret == 0) {
            return 1;
        }
    }
    return 0;
}

int main() {
    char arr1[] = "abcdef";
    char arr2[] = "cdefab";
    int ret = is_left_move(arr1,arr2);
    if (ret == 1) {
        printf("yes");
    }else
    {
        printf("no");
    }
    return 0;
}

方法二:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
#include <string.h>
int is_left_move(char* str1,char* str2)
{
    int len1 = strlen(str1);
    int len2 = strlen(str2);
    if (len1 != len2) {
        return 0;
    }
    //1、在str1字符串中追加一个str1字符串
    //strcat(str1,str1);//err,strcat函数不能自己追加自己
    strncat(str1,str1,len1);
    //2、判断str2指向的字符串是否是str1指向的字符串的字串
    //strstr - 用于找子串
    char * ret = strstr(str1, str2);
    if (ret == NULL)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

int main() {
    char arr1[30] = "abcdef";
    char arr2[] = "cdefab";
    int ret = is_left_move(arr1,arr2);
    if (ret == 1) {
        printf("yes\n");
    }else
    {
        printf("no\n");
    }
    return 0;
}

杨氏矩阵

有一个数字矩阵,矩阵从左往右是递增的,从上到下也是递增的,编写程序在这样的矩阵中查询某个数字是否存在。
要求:时间复杂度小于O(N)
时间复杂度小于O(N)就是说查询次数小于N次,也就是说不能遍历这个数组
假设一个杨氏矩阵
123
456
789

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdio.h>
int FindNum(int arr[3][3],int k,int *px,int *py)
{
    int x = 0;
    int y = *py-1;
    while (x<=*px-1 && y>=0) {
        if (arr[x][y] > k) {
            y--;
        }
        else if(arr[x][y] < k)
        {
            x++;
        }else{
            *px = x;
            *py = y;
            return 1;
        }
    }
    return 0;
}

int main() {
    int arr[3][3] = {{11,22,33},{44,55,66},{77,88,99}};
    int k = 33;
    int x = 3;
    int y = 3;
    //返回型参数
    int ret = FindNum(arr,k,&x,&y);
    if (ret==1)
    {
        printf("我有K\n");
        printf("下标是:%d %d",x,y);
    }
    else
    {
        printf("我没K\n");
    }
    return 0;
}