只AC了第一题和第三题,第二题对了50%,应该能拿500分(1.100分,2.200分,3.300分)。

1.一个M*N的矩阵,从左上角开始从1顺时针旋转报数,并保存个位数是7,十位数是奇数的位置的坐标。

思路

和力扣螺旋矩阵这道题思路是一样的。顺时针遍历,并判断当前走的步数是否满足条件即可。

代码

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

using namespace std;

int main()
{
    int m, n;
    cin >> m >> n;
    int up = 0, down = m - 1, left = 0, right = n - 1;
    int nums = 0;
    vector<vector<int>> res;
    if (n < 10 || n > 1000 || m < 10 || m > 1000)    //判断输入合法性
    {
        cout << "[" << "]" << endl;
        system("pause");
        return 0;
    }

    while (nums < m * n)
    {
        for (int i = left; i <= right && up <= down && nums < m * n; i++)
        {
            nums++;
            if (nums % 10 == 7 && (nums / 10) % 2 == 1)
            {
                cout <<"nums = " << nums << endl;
                vector<int> temp = { up, i };
                res.push_back(temp);
            }
        }
        up++;
        for (int i = up; i <= down && left <= right && nums < m * n; i++)
        {
            nums++;
            if (nums % 10 == 7 && (nums / 10) % 2 == 1)
            {
                cout << "nums = " << nums << endl;
                vector<int> temp = { i, right };
                res.push_back(temp);
            }
        }
        right--;
        for (int i = right; i >= left && up <= down && nums < m * n; i--)
        {
            nums++;
            if (nums % 10 == 7 && (nums / 10) % 2 == 1)
            {
                cout << "nums = " << nums << endl;
                vector<int> temp = { down, i };
                res.push_back(temp);
            }
        }
        down--;
        for (int i = down; i >= up && left <= right && nums < m * n; i--)
        {
            nums++;
            if (nums % 10 == 7 && (nums / 10) % 2 == 1)
            {
                cout << "nums = " << nums << endl;
                vector<int> temp = { i, left };
                res.push_back(temp);
            }
        }
        left++;
    }

    cout << "[";
    for (int i = 0; i < res.size(); i++)
    {
        if (i > 0)
            cout << ",";
        cout << "[";
        cout << res[i][0] << "," << res[i][1];
        cout << "]";
    }
    cout << "]" << endl;

    system("pause");
    return 0;
}

2. 树的所有可能性(50%)

排列组合暴力求解,没啥技巧,只对了一半。

3. 俄罗斯方块

思路

给定两个字符串 frame 是底下基座,brick 是落下的方块,判断brick落下后,消除完无空行的行后,剩下的最小行数。
这个题一看,脑子里有点印象,前两天刚做过一个大数相乘的题,基本框架是一样的。
首先计算两个字符串的长度 lenF 和 lenB,然后把brick字符串与frame字符串通过一个for循环进行错位相加(错位的位数从0到lenF-lenB),分别计算每种情况下的剩余行数的最大值,然后求全部最大值中的最小值。

代码

#include<iostream>    
#include<string>
#include<vector>
#include<algorithm>
#include<stdio.h>
using namespace std;


int main()
{
    string frame, brick;
    cin >> frame >> brick;
    int lenF = frame.length(), lenB = brick.length();

    int add0 = lenF - lenB;
    int res = 9999999;
    for (int i = add0; i >= 0; i--)        //从第一个字符对齐开始,每次向后移动一位,进行错位相加
    {
        string temp = brick;
        vector<int> arr(lenF, 0);
        for (int j = 0; j < i; j++)        //对落下的方块后进行补0,方便相加
            temp += "0";
        for (int k = lenF - 1; k >= 0; k--)    //对应位置的数相加,保存在数组中
        {
            arr[k] += frame[k] - '0';
            if (k - (add0 - i) >= 0)
                arr[k] += temp[k - (add0 - i)] - '0';
        }
        int maxtemp = -9999999, mintemp = 9999999, maxH = -9999999;
        for (int i = 0; i < arr.size(); i++)    //求每次错位相加消除后,剩下的最高的一列的高度
        {
            maxtemp = max(maxtemp, arr[i]);
            mintemp = min(mintemp, arr[i]);
            maxH = max(maxH, maxtemp - mintemp);
        }
        res = min(res, maxH);                    //求每次错位相加的情况中的最小高度

    }
    cout << res << endl;

    system("pause");
    return 0;
}