编程练习赛42+二维动态数组的输入总结

题目1 : 对局匹配

时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
小Hi开发了一个在线玩斗地主的游戏平台。现在平台上有N名用户正在寻找对局,其中第i名用户的积分是Ai。  

小Hi希望自己的平台可以自动将这N名用户匹配成尽量多的3人牌局。同时他希望一局中的3名用户两两之间的积分差不超过K。  

你能帮小Hi实现这个自动对局匹配的算法吗?  

假设现在正有7人在寻找对局,积分分别是[30, 31, 30, 34, 33, 32, 34]并且K = 1,这时最多可以匹配出2局:[30, 31, 30]和[34, 33, 34]。  

输入
第一行包含两个整数,N和K。  (1 ≤ N ≤ 100000, 1 ≤ K ≤ 100000)  

第二行包含N整数Ai。(0 ≤ Ai ≤ 100000)

输出
一个整数表示最多能匹配出的对局数量。

样例输入
7 2  
30 31 30 34 33 32 34
样例输出
2

总结:这题其实不难,有几个小点需要注意,为了防止越界,自己写for循环里面写的是N-3,,但是没有写等于,这里需要注意,比如N-K,倒数第k个节点,已经是第几个了,所以相当与多减了1,因此需要for循环里面写等于。

这题需要首先排序,这样才好进行处理。

for (int i = 0; i <= N - 3;) {
    if (check(num,i,K)) {
        ++cnt;
        i = i + 3;
    }
    else {
        ++i;
    }
}
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
bool check(vector<int> &num,int begin,int K) {
    int i = begin;
    if (num[i + 2] - num[i + 1] > K) {
        return false;
    }
    else if (num[i + 1] - num[i ] > K) {
        return false;
    }
    else if(num[i + 2] - num[i] > K) {
        return false;
    }
    return true;

}

int main() {
    int N, K;
    cin >> N >> K;
    vector<int> num;
    for (int i = 0; i < N; ++i) {
        int tmp;
        cin >> tmp;
        num.push_back(tmp);
    }
    sort(num.begin(), num.end());
    int cnt = 0;
    for (int i = 0; i <= N - 3;) {
        if (check(num,i,K)) {
            ++cnt;
            i = i + 3;
        }
        else {
            ++i;
        }
    }
    cout << cnt << endl;
    system("pause");
}

题目2 : 稀疏矩阵乘积

时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
给定两个N × N的稀疏矩阵A和B,其中矩阵A有P个元素非0,矩阵B有Q个元素非0。请计算两个矩阵的乘积C = A × B并且输出C中所有非0的元素。

输入
第一行包含三个整数N, P, Q    

以下P行每行三个整数i, j, k表示A矩阵的一个非0元素:Aij = k  

以下Q行每行三个整数i, j, k表示B矩阵的一个非0元素:Bij = k  

对于80%的数据,1 ≤ N, P, Q ≤ 200  

对于100%的数据, 1 ≤ N, P, Q ≤ 2000, 1 ≤ i, j ≤ N, 0 ≤ k ≤ 100

输出
输出若干行,按先行后列的顺序输出矩阵C的每一个非0元素  

每行三个整数i, j, k表示C矩阵的一个非0元素:Cij = k

样例输入
2 2 4  
1 1 1  
2 2 1  
1 1 1  
1 2 2  
2 1 3  
2 2 4
样例输出
1 1 1  
1 2 2  
2 1 3  
2 2 4

动态输入数组大小,然后将所有位置初始化为0的输入方法*important。

int N;
cin >> N;
vector<int> tmp;
tmp.resize(N);//默认全为0
vector<vector<int>> vec(tmp.size(),vector<int> (tmp.size()));//全部为0

这题有个非常非常非常大的大坑,就是ij其实是第几行和第几列,所以输入的时候需要减去1才能存入数组,检测的方法是输入N= 2,但是有i = 2的行。

这题核心就是记得矩阵相乘的方法:

定义

A 的矩阵,B 的矩阵,那么称 的矩阵C为矩阵AB的乘积,记作 ,其中矩阵C中的第 行第 列元素可以表示为:

如下所示:

思路和LeetCode的这题很像参考

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

vector<vector<int>> multiply(vector<vector<int>>& A, vector<vector<int>>& B) {
    vector<vector<int>> res(A.size(), vector<int>(B[0].size()));
    for (int i = 0; i < A.size(); ++i) {
        for (int k = 0; k < A[0].size(); ++k) {
            if (A[i][k] != 0) {
                for (int j = 0; j < B[0].size(); ++j) {
                    if (B[k][j] != 0) res[i][j] += A[i][k] * B[k][j];
                }
            }
        }
    }
    return res;
}

int main() {
    int N, P, Q;
    cin >> N >> P >> Q;
    //cout << N << P << Q;
    vector<int> tmp;
    tmp.resize(N);
    vector<vector<int>> A(tmp.size(),tmp),B(A),res;
    
    for (int i = 0; i < P; ++i) {
        int row = 0, col = 0, value = 0;
        cin >> row >> col >> value;
        A[row - 1][col - 1] = value;
    }     
    for (int j = 0; j < Q; ++j) {
        int row = 0, col = 0, value = 0;
        cin >> row >> col >> value;
        B[row - 1][col - 1] = value;

    }
    res = multiply(A, B);
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            if (res[i][j] != 0) {
                cout << i + 1 << " " << j + 1 << " " << res[i][j];
                cout << endl;
            }
            
        }        
    
    }
    system("pause");
}
原文地址:https://www.cnblogs.com/dingxiaoqiang/p/8157909.html