动态矩阵(指针与堆内存分配)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

未知一个整数矩阵的大小,在程序运行时才会输入矩阵的行数m和列数n
要求使用指针,结合new方法,动态创建一个二维数组,并求出该矩阵的最小值和最大值,可以使用数组下标法。
不能先创建一个超大矩阵,然后只使用矩阵的一部分空间来进行数据访问、
创建的矩阵大小必须和输入的行数m和列数n一样

输入

第一行输入t表示t个测试实例
第二行输入两个数字m和n,表示第一个矩阵的行数和列数
第三行起,连续输入m行,每行n个数字,表示输入第一个矩阵的数值
依次输入t个实例

输出

每行输出一个实例的最小值和最大值

样例输入

2
2 3
33 22 11
66 88 55
3 4
19 38 45 14
22 65 87 31
91 35 52 74

样例输出

11 88
14 91

提示

解决方案

#include <iostream>

int main() {
    size_t T;
    std::cin >> T;

    while (T--) {
        size_t row, col;
        std::cin >> row >> col;
        int **matrix = new int *[row];
        for (size_t ir = 0; ir < row; ++ir) {
            matrix[ir] = new int[col];
            for (size_t ic = 0; ic < col; ++ic) {
                std::cin >> matrix[ir][ic];
            }
        }
        int min = matrix[0][0], max = matrix[0][0];
        for (size_t ir = 0; ir < row; ++ir) {
            for (size_t ic = 0; ic < col; ++ic) {
                if (min > matrix[ir][ic]) {
                    min = matrix[ir][ic];
                }
                if (max < matrix[ir][ic]) {
                    max = matrix[ir][ic];
                }
            }
        }
        std::cout << min << ' ' << max << std::endl;
    }

    return 0;
}

三串合一(指针与字符数组)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

输入三个字符串,通过指针读取各个字符串的子串(子串是指字符串中连续的一小部分),把它们合并成一个新字符串

要求:

  1. 三个字符串的创建和输入可以使用数组,也可以不用
  2. 输入后,根据三个字符串的子串的长度,计算出新字符串的长度
  3. 使用动态数组的方法创建新的字符串,并且使用指针读取三个字符串的不同部分,并且复制到新字符串中,要求整个过程都不能使用数组下标
  4. 使用指针输出新的字符串

输入

第一行输入t表示有t个测试实例
连续三行输入三个字符串,每个字符串都包含10个字符
连续三行,每行输入数字a和b,表示每个子串的开始和结束位置。注意字符串的位置是按照一般意义从1开始计算,和编程中的数组位置不同。例如字符串abcdefg,开始位置是3,结束位置是5,那么子串就是cde
依次输入t个实例

输出

每行输出合并后的新字符串

样例输入

2
abcdefghij
ABCDEFGHIJ
aabbccddee
3 5
2 6
8 10
AABBCCDDEE
ffgghhiijj
FFGGHHIIJJ
1 4
5 8
2 7

样例输出

cdeBCDEFdee
AABBhhiiFGGHHI

提示

解决方案

我也不知道我到底要说多少遍,各位大佬才会记得C风格字符串后面还有个’\0’要占空间的…

#include <iostream>

int main() {
    size_t T;
    std::cin >> T;

    while (T--) {
        char strings[3][16];
        std::cin >> strings[0] >> strings[1] >> strings[2];
        size_t bound[3][2] = {}, size = 0;
        for (size_t ir = 0; ir < 3; ++ir) {
            for (size_t ic = 0; ic < 2; ++ic) {
                std::cin >> bound[ir][ic];
                bound[ir][ic] -= 1;
            }
            size += (bound[ir][1] - bound[ir][0]);
        }
        char *string = new char[size + 1];
        char *dst = string;
        for (size_t i = 0; i < 3; ++i) {
            char *src = strings[i] + bound[i][0];
            while (src <= strings[i] + bound[i][1]) {
                *dst++ = *src++;
            }
        }
        *dst = '\0';
        std::cout << string << std::endl;
    }

    return 0;
}

鸡蛋队列(数组,函数)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

将两根筷子平行的放在一起,就构成了一个队列。将带有编号的鸡蛋放到两根筷子之间叫做入队(push),将筷子之间的鸡蛋拿出来叫做出队(pop)。但这两种方式有特殊的定义,对于入队,只能将鸡蛋从队列的尾部向里放入;对于出队,只能将鸡蛋从队列的头部向外将鸡蛋拿出来。

输入

第一行输入一个数T,表示有T组数据 第二行输入一个数N,表示有N(N<=10)种操作 接下来N行,每行一种操作,push表示将编号为x的鸡蛋放入队列中,pop表示拿走队列头部的一个鸡蛋。 数据输入保证合法,队列中没有鸡蛋时不会有出队操作!

输出

输出N种操作完之后,队列中蛋蛋的编号,如果没蛋了,就输出”no eggs!”(不包括引号)每组输出占一行。

样例输入

2
3
push 1 
push 2
push 3
2
push 1
pop

样例输出

1 2 3
no eggs!

提示

数组模拟队列,用下标记录对头、队尾位置。

解决方案

#include <stdio.h>

struct Queue {
    int data[32];
    int head, tail;
};

void push(struct Queue *queue, int data);
void pop(struct Queue *queue);
void show(struct Queue *queue);

int main() {
    int ctrl;
    scanf("%d", &ctrl);

    while (ctrl--) {
        struct Queue queue = {};
        int time;
        scanf("%d", &time);
        while (time--) {
            char operation[8];
            scanf("%s", operation);
            if (operation[1] == 'u') {
                int data;
                scanf("%d", &data);
                push(&queue, data);
            } else {
                pop(&queue);
            }
        }
        show(&queue);
    }

    return 0;
}

void push(struct Queue *queue, int data) {
    queue->data[queue->tail] = data;
    queue->tail += 1;
}

void pop(struct Queue *queue) {
    queue->head += 1;
}

void show(struct Queue *queue) {
    if (queue->head == queue->tail) {
        printf("no eggs!\n");
    } else {
        printf("%d", queue->data[queue->head]);
        for (int i = queue->head + 1; i != queue->tail; ++i) {
            printf(" %d", queue->data[i]);
        }
        printf("\n");
    }
}

分类排序(函数)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

从键盘输入10个整数(10个整数均不相同), 然后再从键盘中输入一个整数a,
如果该整数a为奇数, 且与这10个整数中的任一个数相同,则删掉与a相同的 这个数,并将剩下的9个数按升序排序输出;
若a为偶数, 且与这10个数都不同,则加入a,并将这11个数降序排 序输出;
否则,则将这10个数奇数在前,偶数在后, 降序排列输出。
例如,10个数分别为6,89,34,12, 0,-8,78,15,9,3.
若a为9,则输出为:-8,0,3, 6,12,15,34,78,89.
若a为2,则输出为:89,78, 34,15,12,9,6,3,2,0,-8.
若a为7或者12,则 输出为:89,15,9,3,78,34,12,6,0,-8.
要求:使用函数解决本题,至少编写以下几个函数,
1、升序排序函数void sort(int a[], int n);
2、查找函数int find(int a[],int n,int value)—-在大小为n的a数组中查找值为value的元素,找到就返回元素的下标,找不到,就返回-1;
3、输出函数display(int a[], int n)—逐个输出数组a的元素;
4、反转数组函数void reverse(int a[], int n)—-将数组逆序。

输入

测试数据的组数n
第一组测试数据的10个整数
第一组的整数a
第二组测试数据的10个整数
第二组的整数a
……
第n组测试数据的10个整数
第n组的整数a

输出

第一组数据排序输出
第二组数据排序输出
…….
第n组数据排序输出

样例输入

3
6 89 34 12 0 -8 78 15 9 3
9
6 89 34 12 0 -8 78 15 9 3
2
6 89 34 12 0 -8 78 15 9 3
7

样例输出

-8 0 3 6 12 15 34 78 89
89 78 34 15 12 9 6 3 2 0 -8
89 15 9 3 78 34 12 6 0 -8

提示

解决方案

#include <stdio.h>

#define FAILED_FIND_IN_ARRAY -1

struct Array {
    int data[16];
    int size;
};

void scanToArray(struct Array *array);
int findInArray(struct Array *array, int data);
void sortArray(struct Array *array);
void reverseArray(struct Array *array);
void sortArrayInOddAndEven(struct Array *array);
void printArray(struct Array *array);

int main() {
    int ctrl;
    scanf("%d", &ctrl);

    while (ctrl--) {
        struct Array array = {};
        scanToArray(&array);
        int number;
        scanf("%d", &number);
        if (number % 2 != 0 && findInArray(&array, number) != FAILED_FIND_IN_ARRAY) {
            array.size -= 1;
            for (int i = findInArray(&array, number); i < array.size; ++i) {
                array.data[i] = array.data[i + 1];
            }
            sortArray(&array);
        } else if (number % 2 == 0 && findInArray(&array, number) == FAILED_FIND_IN_ARRAY) {
            array.data[array.size] = number;
            array.size += 1;
            sortArray(&array);
            reverseArray(&array);
        } else {
            sortArrayInOddAndEven(&array);
        }
        printArray(&array);
    }

    return 0;
}

void scanToArray(struct Array *array) {
    array->size = 10;
    for (int i = 0; i < array->size; ++i) {
        scanf("%d", &array->data[i]);
    }
}

int findInArray(struct Array *array, int data) {
    for (int i = 0; i < array->size; ++i) {
        if (array->data[i] == data) {
            return i;
        }
    }
    return -1;
}

void sortArray(struct Array *array) {
    for (int i1 = 0; i1 < array->size - 1; ++i1) {
        for (int i2 = 0; i2 < array->size - 1 - i1; ++i2) {
            if (array->data[i2] > array->data[i2 + 1]) {
                int data = array->data[i2];
                array->data[i2] = array->data[i2 + 1];
                array->data[i2 + 1] = data;
            }
        }
    }
}

void reverseArray(struct Array *array) {
    for (int i = 0; i < array->size / 2; ++i) {
        int data = array->data[i];
        array->data[i] = array->data[array->size - 1 - i];
        array->data[array->size - 1 - i] = data;
    }
}

void sortArrayInOddAndEven(struct Array *array) {
    struct Array odd = {}, even = {};
    for (int i = 0; i < array->size; ++i) {
        if (array->data[i] % 2 == 0) {
            even.data[even.size] = array->data[i];
            even.size += 1;
        } else {
            odd.data[odd.size] = array->data[i];
            odd.size += 1;
        }
    }
    sortArray(&odd);
    reverseArray(&odd);
    sortArray(&even);
    reverseArray(&even);
    for (int i = 0; i < odd.size; ++i) {
        array->data[i] = odd.data[i];
    }
    for (int i = 0; i < even.size; ++i) {
        array->data[i + odd.size] = even.data[i];
    }
}

void printArray(struct Array *array) {
    printf("%d", array->data[0]);
    for (int i = 1; i < array->size; ++i) {
        printf(" %d", array->data[i]);
    }
    printf("\n");
}

计算字符串的长度

时间限制: 1 Sec 内存限制: 128 MB

题目描述

计算字符串S的长度,功能与strlen函数相同,但不能调用库函数strlen,否则不给分。输入的字符串不包含空格。

输入

输入测试组数t
对于每组测试,输入字符串S(长度<=30)

输出

对于每组测试,输出S的长度

样例输入

1
hehe

样例输出

4

提示

解决方案

#include <iostream>

int main() {
    int ctrl;
    std::cin >> ctrl;
    while (ctrl--) {
        char str[64] = {};
        std::cin >> str;
        int length = 0;
        while (str[++length] != '\0');
        std::cout << length << std::endl;
    }

    return 0;
}

单词统计

时间限制: 1 Sec 内存限制: 128 MB

题目描述

编写一个程序,根据单词的出现频率降序打印出所输入的的各个单词。每个单词前标有它的计数值。

输入

各个单词,输入0则表示单词结束

输出

降序打印单词出现的频率和单词。单词频度相同,按出现顺序输出。

样例输入

bad
good
bad
cute
how
good
good
0

样例输出

3 good
2 bad
1 cute
1 how

提示

解决方案

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

struct Pair {
    std::string string;
    int count;
    Pair(std::string &string, int count) : string(string), count(count) {}
};
bool operator==(Pair &pair, const std::string &string) {
    return pair.string == string;
}
bool operator<(const Pair &lhs, const Pair &rhs) {
    return lhs.count > rhs.count; // NG
}

int main() {
    std::vector<Pair> vector;
    std::string string;
    std::cin >> string;
    while (string != "0") {
        std::vector<Pair>::iterator it = std::find(vector.begin(), vector.end(), string);
        if (it != vector.end()) {
            it->count += 1;
        } else {
            vector.push_back(Pair(string, 1));
        }
        std::cin >> string;
    }
    std::sort(vector.begin(), vector.end());
    for (int i = 0; i < vector.size(); ++i) {
        std::cout << vector[i].count << ' ' << vector[i].string << std::endl;
    }

    return 0;
}

安卓 通过adb将TF(SD)卡用作内置存储

手上有个360 N6,平时当备用机,存点音乐视频什么的,存储空间不太够,于是乎买了张TF卡插上。(其实应该去看看紫光的超级SIM卡能不能用的,深圳联通公众号上也发可以参加预存话费赠卡的活动了)

我的第一部智能手机买的是黑莓Priv,插卡之后会提示格式化成外置的便携式存储(可以拔出来在不同设备,比如电脑上交换数据)还是内置存储(不能用在其它机器上),并且使用非常正常。

好了问题来了,N6插卡之后只能格式化成外置存储(?),这就很蛋疼,插卡的意义似乎就不大。后面发现其实可以用adb开启,虽然好像还是有点问题。

But how?

可以用sm来做到。

首先连续多次点按设置->系统->关于手机->版本号,打开开发者选项,然后在开发者选项打开USB调试。此时可以把手机连接到电脑上了。

我正在使用Android Studio,安装过Android SDK,可以直接在C:\Users\domain\AppData\Local\Android\Sdk\platform-tools中找到adb工具。没有也没关系,从SDK平台工具版本说明 | Android 开发者 | Android Developers可以下载到独立的工具包。

已经有了platform-tools之后,进入该目录,按住Shift再点击鼠标右键可以在该目录打开PowerShell。此时运行:

PS C:\Users\domain\AppData\Local\Android\Sdk\platform-tools> .\adb.exe devices
List of devices attached
* daemon not running; starting now at tcp:5037
* daemon started successfully
1f95707d        unauthorized

显示未授权,此时手机上应该会弹窗是否允许电脑进行调试(以及一个密钥),允许后再次执行:

PS C:\Users\domain\AppData\Local\Android\Sdk\platform-tools> .\adb.exe devices
List of devices attached
1f95707d        device

此时可以:

PS C:\Users\domain\AppData\Local\Android\Sdk\platform-tools> .\adb.exe shell
QK1707:/ $

有了手机的Shell了,尝试sm工具查看存储:

QK1707:/ $ sm list-disks
disk:179,64

如果手机允许:

QK1707:/ $ sm has-adoptable
true

反之则可能需要尝试sm set-force-adoptable true。接下来 就可以:

QK1707:/ $ sm partition disk:179,64 private

来将存储卡格式化为内置存储。如果执行:

QK1707:/ $ sm partition disk:179,64 mixed 30

可以将部分空间格式化为内置存储,另一部分(30%)作为便携式存储。

此时可以在设置中看到存储卡已经被设置为内置存储了。发现容量显示有问题,而且迁移也有点问题。网友分享格机后,安装应用不要打开马上迁移就没有问题。决定这几天格机再试一下。

引用:
android – How to turn a portable SD card into internal storage via ADB command? – Stack Overflow
透過ADB方式開啟與配置Adoptable Storage空間(免root) @ 老梁’s blog :: 隨意窩 Xuite日誌
360N7Lite免root安装应用到内存卡的方法及其它玩机教程-更新自动安装到内存卡_360社区

Windows下利用WSL使用pwntools

(以下是小学生日记式开头)

今天我们来讨论一下在Windows上使用pwntools的姿势。

WSL到现在也有一段时间了,现在你也可以选择玩WSL 2。PyCharm支持它挺久了,下面就来简单废话一下。

如果你不打算用IDE…

那似乎并不需要看我下面在废话什么了…你只需要:

  1. 控制面板->程序->启用或关闭Windows功能里选上适用于Linux的Windows子系统,或是直接打开PowerShell:
    Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
  2. 可以到Microsoft Store搜索WSL,然后下载安装一个适合你的Linux发行版。
  3. 在WSL中安装你所需要的工具,例如python、nano,当然还有pwntools。

然后你就可以愉快地开始撸题了。

准备好WSL和IDE

好了我们来进入正题。这里我就假设你已经根据上面的几句简短的描述安装好了WSL(滑稽.jpg)。现在,你可以选择JetBrains PyCharm,对于学生来说,可以申请教育授权来免费使用Professional版本。

另外,如果你已经拥有了JetBrains IntelliJ IDEA Ultimate,并且不希望再安装一个IDE,你可以安装Python插件来实现。

配置一下

如果你不想看我废话,你可以出门拐弯到这里

不论是PyCharm还是IntelliJ IDEA,新建Project的时候应该都会提示指定Python解释器。选择WSL就可以开始了。

如果已经新建好了一个Project,这个时候你可以在右上角或Settings中找到Project Structure (Ctrl+Alt+Shift+S),找不到的话就两下Shift来Search Everywhere吧。然后选中左侧栏的Platform Settings->SDKs,点击加号并选中Python SDK,就像这样:

PWNTOOLS-1.png
Project Structure->SDKs->Add New SDK

附:当写这篇文章的时候,IntelliJ IDEA还是2019.1,某个小版本里,这里没有WSL选项,当时用SSH Interpreter先顶一下。

Unresolved reference ‘pwn’

确定正确的SDK之后,如果IDE建立索引后,代码中的from pwn import *仍然提示错误:Unresolved reference ‘pwn’,可能可以通过Invalidate Caches来解决。

PWNTOOLS-5.png
Invalidate Caches and Restart

重启后应该就没有问题了。

PWNTOOLS-6.png

引用:
Why PyCharm can’t resolve reference for a remote Docker interpreter?