Week14HomeWork

A-

 Q老师与石头剪刀布(必做)   签到题,不再赘述

B-

Q老师 得到一张 n 行 m 列的网格图,上面每一个格子要么是白色的要么是黑色的。

Q老师认为失去了 十字叉 的网格图莫得灵魂. 一个十字叉可以用一个数对 x 和 y 来表示, 其中 1 ≤ x ≤ n 并且 1 ≤ y ≤ m, 满足在第 x 行中的所有格子以及在第 y 列的 所有格子都是黑色的

例如下面这5个网格图里都包含十字叉

第四个图有四个十字叉,分别在 (1, 3), (1, 5), (3, 3) 和 (3, 5).

下面的图里没有十字叉

Q老师 得到了一桶黑颜料,他想为这个网格图注入灵魂。 Q老师 每分钟可以选择一个白色的格子并且把它涂黑。现在他想知道要完成这个工作,最少需要几分钟?

Input

第一行包含一个整数 q (1 ≤ q ≤ 5 * 10^4) — 表示测试组数

对于每组数据:

第一行有两个整数 n 和 m (1 ≤ n, m ≤ 5 * 10^4, n * m ≤ 4 * 10^5) — 表示网格图的行数和列数

接下来的 n 行中每一行包含 m 个字符 — '.' 表示这个格子是白色的, '*' 表示这个格子是黑色的

保证 q 组数据中 n 的总和不超过 5 * 10^4, n*m 的总和不超过 4 * 10^5

Output

答案输出 q 行, 第 i 行包含一个整数 — 表示第 i 组数据的答案

Example

Input
9
5 5
..*..
..*..
*****
..*..
..*..
3 4
****
.*..
.*..
4 3
***
*..
*..
*..
5 5
*****
*.*.*
*****
..*.*
..***
1 4
****
5 5
.....
..*..
.***.
..*..
.....
5 3
...
.*.
.*.
***
.*.
3 3
.*.
*.*
.*.
4 4
*.**
....
*.**
*.**
Output
0
0
0
0
0
4
1
1
2

代码分析:
  使用一维数组来储存矩阵,长宽为n,m ,index(i,j) = i*m+j 。每次记录每行每列‘*’的个数,选最大的几组存下来坐标,然后验证这个坐标的交叉处是不是‘*’ ,就可以得到答案了。
  这道题其实不难,要注意的一点就是不能直接用二维数据存矩阵,因为oj上会超时,其实看数据范围也可以知道出题者的意图,0<n,m<1e4 ,而 0<n*m<5*1e5 ,哈哈,就是要卡一下你的内存。
  但是这道题我wa了很多发,心态崩了,后来发现就是计算index的时候整错了一个数QAQ 。
#include<iostream>
#include<cstdlib>
#include<vector>
#include<string>
#include<cstring> 

using namespace std;
#define maxn 40000010

struct Matrix {
    int n;
    int m;
    bool data[maxn + 100];
    bool get(int i, int j) {
        return data[i*m + j];
    }
    void change(int i, int j, char ch) {
        bool temp;
        if (ch == '*') {//黑色 
            temp = 1;
        }
        else {
            temp = 0;
        }
        data[i*m + j] = temp;
    }
};

int q;
Matrix Matr;
int n, m;

int main() {
    cin >> q;
    for (int ii = 0; ii < q; ii++) {
        //Matrix Matr;
        scanf("%d%d", &n, &m);
        Matr.n = n;
        Matr.m = m;
        memset(Matr.data,0,n*m);
        char temp;
        int sum1 = 0;
        int sum2 = 0;
        int tempxin = 0;
        int row;
        int col;

        vector<int> a, b;

        for (int i = 0; i < n; i++) {
            tempxin = 0;
            for (int j = 0; j < m; j++) {
                cin >> temp;
                Matr.change(i, j, temp);
                if (temp == '*') {
                    tempxin++;
                }
            }
            //sum1 = max(tempxin, sum1);
            if (sum1 < tempxin) {
                sum1 = tempxin;
                row = i;
                a.clear();
                a.push_back(i);
            }
            else if (sum1 == tempxin) {
                a.push_back(i);
            }
        }
        for (int j = 0; j < m; j++)
        {
            tempxin = 0;
            for (int i = 0; i < n; i++) {
                if (Matr.get(i, j) == 1) {
                    tempxin++;
                }
            }
            if (sum2 < tempxin) {
                sum2 = tempxin;
                col = j;
                b.clear();
                b.push_back(j);
            }
            else if (sum2 == tempxin) {
                b.push_back(j);
            }
        }

        bool flag = false;
        for (int i = 0; i < a.size(); i++) {
            for (int j = 0; j < b.size(); j++) {
                if (Matr.get(a[i], b[j]) == 0) {
                    flag = true;
                    break;
                }
            }
        }
        
        

        if (flag)
        { 
            cout << n + m - sum1 - sum2 -1 << endl;
        }
        else {    
            cout << n + m - sum1 - sum2 << endl;
        }

        
    }
}

 

C ---  矩阵快速幂

Q老师 对数列有一种非同一般的热爱,尤其是优美的斐波那契数列。

这一天,Q老师 为了增强大家对于斐波那契数列的理解,决定在斐波那契的基础上创建一个新的数列 f(x) 来考一考大家。数列 f(x) 定义如下:

当 x < 10 时,f(x) = x;
当 x ≥ 10 时,f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10),ai 只能为 0 或 1。

Q老师 将给定 a0~a9,以及两个正整数 k m,询问 f(k) % m 的数值大小。

聪明的你能通过 Q老师 的考验吗?

Input

输出文件包含多组测试用例,每组测试用例格式如下:

第一行给定两个正整数 k m。(k < 2e9, m < 1e5)

第二行给定十个整数,分别表示 a0~a9。

Output

对于每一组测试用例输出一行,表示 f(k) % m 的数值大小。

Sample Input
10 9999
1 1 1 1 1 1 1 1 1 1
20 500
1 0 1 0 1 0 1 0 1 0
Sample Output
45
104

这道题其实考的是矩阵快速幂这个知识点。


先贴上代码:
#include<iostream>
#include<string>
#include<cstring>

using namespace std;

int n = 10;

int k;
int m;

struct Matrix{
    int x[15][15];
    Matrix(){ 
        memset(x, 0, sizeof(x));
    }
    
    Matrix operator*(Matrix t){
        Matrix tem;
        for (int i = 0; i < n; i++){
            for (int j = 0; j < n; j++){
                tem.x[i][j] = 0;
                for (int k = 0; k < n; k++){
                    tem.x[i][j]=tem.x[i][j]+x[i][k]*t.x[k][j]%m;
                    tem.x[i][j]=tem.x[i][j]%m;
                }
            }
        }
        return tem;
    }
    Matrix(const Matrix &t){
        memcpy(x,t.x,sizeof(x));
    }
};

Matrix quick_pow(Matrix a, int x){
    Matrix ret;
    for (int i = 0; i <= 9; i++)
    {
        ret.x[i][i] = 1;
    }
    while (x)
    {
        if (x & 1) ret = ret * a;
        a = a * a;
        x >>= 1;
    }
    return ret;
}
int main(){
    int ans;
    
    while (cin >> k >> m){
        Matrix a;
        ans = 0;
        for (int i = 0; i <= 9; i++){
            cin >> a.x[0][i];
        }
        for (int i = 1; i <= 9; i++){
            a.x[i][i - 1] = 1;
        }
        if (k <= 9){
            ans = k % m;
        }else if (k >= 10){
            a = quick_pow(a, k - 9);
            for (int i = 0; i <= 9; i++){
                ans += (a.x[0][i] * (9 - i)) % m;
                ans %= m;
            }
        }
        cout << ans << endl;
    }
    return 0;
}

 



posted on 2020-06-09 20:32  FFchopin  阅读(136)  评论(0编辑  收藏  举报

导航