struck有关与集合有关

what a fucking day
this morning , though I really wanted to take history class which is the last lesson of this term, but I was too sleepy to wake up.
After a silent math class, I went to library to type C code.
that made me want to go die.
hhhhhh

  • 射击问题struck

Erin最近很喜欢玩射击游戏。她刚考完了C语言的期末考试,感觉很溜,于是又来到了射击娱乐场放松一下。和上次一样,先从老板那租了一把步枪和装有N发子弹的弹夹。在射击的过程中,Erin每次都有两种选择:从弹夹中取出一颗子弹上膛,或者打一发子弹出去。注意:所有的子弹都从枪口上膛。Erin感觉这有点像C语言课程中的“栈”的特点。因此在打完了这N发子弹之后,她想验证一下这些子弹打出来的顺序是不是真的满足“栈”的特性。假设N颗子弹的编号为1,2,…,N。子弹从弹夹中取出的顺序也是从1到N。给定一个子弹被打出的顺序,你可以帮Erin验证其是否满足“栈”的打出顺序吗?

可能有多个测试输入,第一行给出总共的测试输入的个数T,和每个测试输入的子弹数N。(0 < T < 20, 0 < N < 10)

每个测试输入只有一行:用空格隔开的N个数,表示子弹打出的编号顺序。

输出YES或者NO表示判断结果

例如

INPUT:

2 4

4 3 2 1

4 2 3 1

OUTPUT:

YES

NO
一个数之后的数必须降序排列

#include<stdio.h>
int main() {
    int t, n;
    scanf("%d %d", &t, &n);
    while (t--) {
        int s[15] = {};
        int temp;  // 存放s[i]之后可能存在的第一个比s[i]小的
        int flag1;  // 标识s[i]之后是否存在比s[i]小的
        int flag2;  // 标识出栈序列是否非法
        int i, j, k;
        for (i = 1; i <= n; i++)
            scanf("%d", &s[i]);
        for (i = 1; i < n; i++) {
            flag1 = 0;
            flag2 = 0;
            for (j = i + 1; j <= n; j++)  // 寻找s[i]之后第一个比s[i]小的
                if (s[j] < s[i]) {  // s[i]之后存在比s[i]小的
                    temp = s[j];  // s[j]是s[i]之后第一个比s[i]小的
                    flag1 = 1;
                    break;
                }
            if (flag1 == 1)
                for (k = j + 1; k <= n; k++)
                    if (s[k] < s[i])  // s[j]之后如果还有比s[i]小的数
                        if (s[k] >= temp) {  // 出栈序列非法
                            flag2 = 1;
                            break;
                        }
                        else  // 都必须小于它之前的一个比s[i]小的数
                            temp = s[k];  // 更新temp
            if (flag2 == 1) {
                printf("No\n");
                break;
            }
        }
        if (flag2 == 0)
            printf("Yes\n");
        }
        return 0;
}
  • 集合有关交集并集
    There are two groups of some numbers(0~50). each group should be input in a set(remove the duplicate numbers).
    And then output the two set, intersection and union of the two set.
    Input format:
    first line: a couple of numbers and end of -1.
    second line: a couple of numbers and end of -1.
    Output format:
    first line:Output the first set.
    second line: Output the second set.
    third line: Output the intersection of the two set.
    fourth line:Output the union of the two set.
    All the numbers in the set should be output by ascending oder.
    Each line behind the numbers, there is a space ’ ‘.
    For example:
    [Input]
    1 2 3 6 5 4 1 2 3 -1
    3 2 3 2 1 0 -1
    [Output]
    1 2 3 4 5 6
    0 1 2 3
    1 2 3
    0 1 2 3 4 5 6
    [Input]
    0 -1
    1 -1
    [Output]
    0
    1
    0 1
    这是我自己写的代码,很低级,也不够优化,但是比较好理解
#include<stdio.h>

int sort(int *p, int n);  // 给数组去重复排序的函数
void intersection(int *p, int n, int *q, int m);  // 求交集的函数
int un(int *p, int n, int *q, int m); // 求并集的函数
 // 函数主体
int main() {
    int a[100] = {0};
    int b[100] = {0};
    int length1 = 0, length2 = 0;
    //给数组a,b赋值
    scanf("%d", &a[length1]);
    while (a[length1] != -1) {
        length1++;
        scanf("%d", &a[length1]);
    }

    scanf("%d", &b[length2]);
    while (b[length2] != -1) {
        length2++;
        scanf("%d", &b[length2]);
    }
    sort(a, length1);//给数组a, b 去重复排序并输出
    sort(b, length2);
    intersection(a, length1, b, length2);//求交集
    un(a, length1, b, length2);//求并集
    return 0;
}

int sort(int *p, int n) {
    int i, j, k;
    //冒泡排序升序
    for (i = 0; i < n; i++) {
        for (j = 0; j < n - i - 1; j++)
            if (p[j] > p[j+1]) {
                k = p[j];
                p[j] = p[j+1];
                p[j+1] = k;
            }
    }
    //去重复输出数组
    printf("%d ", p[0]);
    for (i = 1; i < n; i++) {
        if (p[i] == p[i-1])
            continue;
        printf("%d ", p[i]);
    }
    printf("\n");
}
//这个算法不够优化
void intersection(int *p, int n, int *q, int m) {
    int i, j;
    int t = 0, flag = 0;
    int temp[3000] = {0}; // 这个数组比较大,但是为了防止溢出必须要开大一点至少2500
    //判断两个数组里面有没有一样的元素,有就写入数组temp中
    for (i = 0; i < n; i++) {
        for (j = 0; j < m; j++) {
            if (p[i] == q[j]) {
                temp[t] = p[i];
                t++;
                flag = 1;  //  如果两个没有交集,则flag为0,就会输出'\0',而不是temp[0]
            }
        }
    }
    if (flag != 0) {
        sort(temp, t);  //  求得新数组再次去重复排序
    } else {
        printf("\n");
    }
}

int un(int *p, int n, int *q, int m) {
    int i, j, k;
    int t[101] = {0};
//  如果,a的第一个比b的第一个小,数组t中写入a的第一个数,a的下标加1.如果,a的第一个比b的第一个大,数组t中写入b的第一个数,b的下标加1.如果,相等,写入任何一个,ab下标加1.知道 a或b全都比较完,把剩余的数写入t中
    for (i = 0, j = 0, k = 0; ; k++) {
        if (p[i] == q[j]) {
            t[k] = p[i];
            i++;
            j++;
        } else if (p[i] < q[j]) {
            t[k] = p[i];
            i++;
        } else if (p[i] > q[j]) {
            t[k] = q[j];
            j++;
        }
        if ((i == n) || (j == m))
            break;
    }
    if ((i == n) && (j < m)) {
        for (j; j < m; j++) {
            k++;
            t[k] = q[j];
        }
    } else if (i < n && j == m) {
        for (i; i < n; i++) {
            k++;
            t[k] = p[i];
        }
    }
// 对t去重复排序
    sort(t, k+1);
}

这是大神的代码我来膜拜一下

#include <stdio.h>

// set and sort代码
int inputSet(int set[]) {
    int n, i, j, temp;
    int count = 0;

    while (scanf("%d", &n)) {
        if (n == -1)
            break;
        for (i = 0; i < count; ++i) {
            if (n == set[i])
                break;
        }

        if (i == count) {
            set[count] = n;
            count++;
        }
    }

    for (i = 0; i < count - 1; ++i)  //  选择排序
    for (j = i + 1; j < count; ++j)
        if (set[i] > set[j]) {
            temp = set[i];
            set[i] = set[j];
            set[j] = temp;
        }

    return count;
}

// 输出交集
void outputITS(int a[], int count_a, int b[], int count_b) {
    int i, j;
    for (i = 0; i < count_a; ++i) {
        for (j = 0; j < count_b; ++j) {
            if (a[i] == b[j])
                printf("%d ", a[i]);
        }
    }
    printf("\n");
}

// 输出并集
void outputUNI(int a[], int count_a, int b[], int count_b) {
    int i, j;
    i = j = 0;

    while (i != count_a && j != count_b) {
        if (a[i] < b[j]) {
            printf("%d ", a[i]);
            i++;
        } else if (a[i] == b[j]) {
            printf("%d ", a[i]);
            i++;
            j++;
        } else if (a[i] > b[j]) {
            printf("%d ", b[j]);
            j++;
        }
    }

    if (i != count_a) {
        for (; i < count_a; ++i)
            printf("%d ", a[i]);
    }

    if (j != count_b) {
        for (; j < count_b; ++j)
            printf("%d ", b[j]);
    }
    printf("\n");
}

// 输出集合
void output(int a[], int c) {
    int i;
    for (i = 0; i < c; ++i)
        printf("%d ", a[i]);
    printf("\n");
}

int main() {
    int a[50];
    int b[50];
    int count_a, count_b;

    count_a = inputSet(a);
    count_b = inputSet(b);

    output(a, count_a);
    output(b, count_b);
    outputITS(a, count_a, b, count_b);
    outputUNI(a, count_a, b, count_b);

    return 0;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值