2021.01.30刷题总结

J - Fire!

Joe works in a maze. Unfortunately, portions of the maze have
caught on fire, and the owner of the maze neglected to create a fire
escape plan. Help Joe escape the maze.
在这里插入图片描述
Given Joe’s location in the maze and which squares of the maze
are on fire, you must determine whether Joe can exit the maze before
the fire reaches him, and how fast he can do it.
Joe and the fire each move one square per minute, vertically or
horizontally (not diagonally). The fire spreads all four directions
from each square that is on fire. Joe may exit the maze from any
square that borders the edge of the maze. Neither Joe nor the fire
may enter a square that is occupied by a wall.
Input
The first line of input contains a single integer, the number of test
cases to follow. The first line of each test case contains the two
integers R and C, separated by spaces, with 1 ≤ R, C ≤ 1000. The
following R lines of the test case each contain one row of the maze. Each of these lines contains exactly
C characters, and each of these characters is one of:
• #, a wall
• ., a passable square
• J, Joe’s initial position in the maze, which is a passable square
• F, a square that is on fire
There will be exactly one J in each test case.
Output
For each test case, output a single line containing ‘IMPOSSIBLE’ if Joe cannot exit the maze before the
fire reaches him, or an integer giving the earliest time Joe can safely exit the maze, in minutes.
Sample Input
2
4 4

#JF#
#…#
#…#
3 3

#J.
#.F
Sample Output
3
IMPOSSIBL

这题的解题思路不是很难,在走迷宫的基础上多加了一个火,火会朝四个方向蔓延
我们定义两个队列,一个people来保存人走过的地方,一个fire来保存火经过的地方
然后主函数每循环一次,更新一下火的路径,再更新一下人的路径就行了
要注意的是,最开始的火源不只一个,要注意
虽然不难,但是我被自己蠢哭了,犯了一个特别低级的错误,如下:
假设people是一个装了pos变量的队列容器,我用下面这行代码去遍历people队列:

for (pos it = people.front(); people.size(); people.pop())
{
	//这里是代码
}

这个for循环虽然把people跑了个边,但是it变量没有更新呀
被自己蠢哭,我还以为是我逻辑上面哪个地方出了问题
下面是AC代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1100;
char Map[maxn][maxn];
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
int r, c;
struct pos
{
    int x, y;
};
bool isescaped(queue<pos> &people)//用来判定有没有逃出去
{
    queue<pos> newp = people;
    while (newp.size())
    {
        pos it = newp.front();
        newp.pop();
        if (it.x == 0 || it.x == r - 1 || it.y == 0 || it.y == c - 1)
            return true;
    }
    return false;
}
void updataPeople(queue<pos> &people)//更新people的路径
{
    queue<pos> newp;
    pos temp;
    while (people.size())
    {
        pos it = people.front();
        people.pop();
        for (int i = 0; i < 4; i++)
        {
            int nx = it.x + dx[i], ny = it.y + dy[i];
            if (nx >= 0 && nx < r && ny >= 0 && ny < c && Map[nx][ny] == '.')
            {
                Map[nx][ny] = 'J';
                temp.x = nx, temp.y = ny;
                newp.push(temp);
            }
        }
    }
    people = newp;
}
void updataFire(queue<pos> &fire)//更新fire的路径
{
    queue<pos> newp;
    pos temp;
    while (fire.size())
    {
        pos it = fire.front();
        fire.pop();
        for (int i = 0; i < 4; i++)
        {
            int nx = it.x + dx[i], ny = it.y + dy[i];
            if (nx >= 0 && nx < r && ny >= 0 && ny < c && (Map[nx][ny] == '.' || Map[nx][ny] == 'J'))
            {
                Map[nx][ny] = 'F';
                temp.x = nx, temp.y = ny;
                newp.push(temp);
            }
        }
    }
    fire = newp;
}
int main(void)
{
    int n;
    cin >> n;
    while (n--)
    {
        cin >> r >> c;
        pos p, f;
        queue<pos> people, fire; //两个队列来记录人和火的状态
        for (int i = 0; i < r; i++)
            for (int j = 0; j < c; j++)
            {
                cin >> Map[i][j];
                if (Map[i][j] == 'J') //找到人的坐标
                {
                    p.x = i;
                    p.y = j;
                    people.push(p);
                }
                if (Map[i][j] == 'F') //找到火的坐标
                {
                    f.x = i;
                    f.y = j;
                    fire.push(f);
                }
            }
        int step = 1;
        while (people.size())
        {
            if (isescaped(people)) //判定有没有逃出去
            {
                cout << step << endl;
                break;
            }
            step++;//步数+1
            updataFire(fire); //更新火的状态
            updataPeople(people); //更新人的状态
        }
        if (people.size() == 0)//如果人都没了,说明被火烧死了
            cout << "IMPOSSIBLE" << endl;
    }
    return 0;
}

K-divisible Sum

You are given two integers n and k.
You should create an array of n positive integers a1,a2,…,an such that the sum (a1+a2+⋯+an) is divisible by k and maximum element in a is minimum possible.
What is the minimum possible maximum element in a?
Input
The first line contains a single integer t (1≤t≤1000) — the number of test cases.
The first and only line of each test case contains two integers n and k (1≤n≤109; 1≤k≤109).
Output
For each test case, print one integer — the minimum possible maximum element in array a such that the sum (a1+⋯+an) is divisible by k.
Example
Input
4
1 5
4 3
8 8
8 17
Output
5
2
1
3
Note
In the first test case n=1, so the array consists of one element a1 and if we make a1=5 it will be divisible by k=5 and the minimum possible.
In the second test case, we can create array a=[1,2,1,2]. The sum is divisible by k=3 and the maximum is equal to 2.
In the third test case, we can create array a=[1,1,1,1,1,1,1,1]. The sum is divisible by k=8 and the maximum is equal to 1.

有n个数字,他们的和是k的倍数,我们要使得n个数字里最大的数字最小化
这题就是
ans=k/n,如果k/n有余数的话,ans++
不过前提是k>=n,如果k<n,那我们就用ak,使得ak>=n,且a*k要最小
AC代码

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
int main(void)
{
    int t;
    cin >> t;
    while (t--)
    {
        ull n, k;
        cin >> n >> k;
        ull a = n / k + ((n % k) > 0);
        k *= a;
        cout << (k / n + ((k % n) > 0)) << endl;
    }
}

Nezzar and Lucky Number

Nezzar’s favorite digit among 1,…,9 is d. He calls a positive integer lucky if d occurs at least once in its decimal representation.
Given q integers a1,a2,…,aq, for each 1≤i≤q Nezzar would like to know if ai can be equal to a sum of several (one or more) lucky numbers.
Input
The first line contains a single integer t (1≤t≤9) — the number of test cases.
The first line of each test case contains two integers q and d (1≤q≤104, 1≤d≤9).
The second line of each test case contains q integers a1,a2,…,aq (1≤ai≤109).
Output
For each integer in each test case, print “YES” in a single line if ai can be equal to a sum of lucky numbers. Otherwise, print “NO”.
You can print letters in any case (upper or lower).
Example
Input
2
3 7
24 25 27
10 7
51 52 53 54 55 56 57 58 59 60
Output
YES
NO
YES
YES
YES
NO
YES
YES
YES
YES
YES
YES
NO
Note
In the first test case, 24=17+7, 27 itself is a lucky number, 25 cannot be equal to a sum of lucky numbers.

将数字a拆成若干个数字相加,保证若干个数字里面,每个数字至少有一位是d
思路:
①如果a比d小,肯定不行

②我们可以把a拆成nd+c,这样的话,a就拆成了n个d1个c
如果我们能从n个d里面拿出m (m<n)个d,使得m
d+c是10的倍数,那么就有解,否则无解

③如果a>10d,那么肯定有解,因为a至少能拆成nd+c (n>10),这样的话,不管c是多少,md+c 一定能凑成10都倍数。
原理:假设x=10-d,那么 (n+1)*d的个位 一定会比 ==n
d的个位== 小 x ,就是说n每加一次,nd的 个位数 就会减少x。
像这样如果 n加了十次 ,那么 0~9 这十个数字,一定都会在 ==n
d的个位== 上 出现 一次。
所以,只要n>10,不管c是多少,一定能够凑成十的倍数。
AC代码

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
int main(void)
{
    int t;
    cin >> t;
    while (t--)
    {
        ull q, d, a;
        cin >> q >> d;
        for (int i = 0; i < q; i++)
        {
            scanf("%llu", &a);
            if (a % d == 0)
                cout << "YES" << endl;
            else
            {
                ull x = a / d, y = a % d;
                int count = 0;
                if (a > 10 * d)
                {
                    cout << "YES" << endl;
                    continue;
                }
                while (y % 10 && count < x)
                {
                    y += d;
                    count++;
                }
                if (count < x)
                    cout << "YES" << endl;
                else
                    cout << "NO" << endl;
            }
        }
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值