2021.01.29刷题总结

F - Catch That Cow

Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.
*Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute
*Teleporting: FJ can move from any point X to the point 2 × X in a single minute.
If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?
Input
Line 1: Two space-separated integers: N and K
Output
Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.
Sample Input
5 17
Sample Output
4
Hint
The fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.

今早起来再提交一次居然过了!!!,奇奇怪怪的,没啥改动
思路:
一、在牛的左边:我就把三种情况都做一遍:向左走,向右走,传送,然后比较谁最小
二、如果在牛的右边,我只需要向左走就行了
实现的时候,因为会存在很多重复访问的情况,所以就用了一个visited数组记录访问状态,实现树的剪枝,避免重复操作。
AC代码:

#include <iostream>
#include <queue>
using namespace std;
int n, k;
const int maxn = 110000;
struct node
{
    int pos, step;
};
bool visited[maxn] = {false};
int main(void)
{
    cin >> n >> k;
    queue<node> que;
    node front = {n, 0};
    node temp;
    visited[front.pos] = true;
    que.push(front);
    while (que.size())
    {
        front = que.front();
        que.pop();
        if (front.pos == k)
        {
            cout << front.step << endl;
            return 0;
        }
        向后走一步
        temp = front;
        temp.pos--, temp.step++;
        if (temp.pos >= 0 && visited[temp.pos] == false) //如果该点没有来过,且位置不能越界
        {
            que.push(temp);           //入队
            visited[temp.pos] = true; //该点已经来过
        }
        //向前走一步
        if (front.pos < k)
        {
            temp = front;
            temp.pos++, temp.step++;
            if (temp.pos < maxn && visited[temp.pos] == false) //如果该点没有来过,且位置不能越界
            {
                que.push(temp);           //入队
                visited[temp.pos] = true; //该点已经来过
            }
            //传送
            temp = front;
            temp.pos *= 2, temp.step++;                        //
            if (temp.pos < maxn && visited[temp.pos] == false) //如果该点没有来过,且位置不能越界
            {
                que.push(temp);           //入队
                visited[temp.pos] = true; //该点已经来过
            }
        }
    }
    return 0;
}

K - Prime Path

The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change the four-digit room numbers on their offices.
— It is a matter of security to change such things every now and then, to keep the enemy in the dark.
— But look, I have chosen my number 1033 for good reasons. I am the Prime minister, you know!
— I know, so therefore your new number 8179 is also a prime. You will just have to paste four new digits over the four old ones on your office door.
— No, it’s not that simple. Suppose that I change the first digit to an 8, then the number will read 8033 which is not a prime!
— I see, being the prime minister you cannot stand having a non-prime number on your door even for a few seconds.
— Correct! So I must invent a scheme for going from 1033 to 8179 by a path of prime numbers where only one digit is changed from one prime to the next prime.
Now, the minister of finance, who had been eavesdropping, intervened.
— No unnecessary expenditure, please! I happen to know that the price of a digit is one pound.
— Hmm, in that case I need a computer program to minimize the cost. You don’t know some very cheap software gurus, do you?
— In fact, I do. You see, there is this programming contest going on… Help the prime minister to find the cheapest prime path between any two given four-digit primes! The first digit must be nonzero, of course. Here is a solution in the case above.
1033
1733
3733
3739
3779
8779
8179
The cost of this solution is 6 pounds. Note that the digit 1 which got pasted over in step 2 can not be reused in the last step – a new 1 must be purchased.
Input
One line with a positive number: the number of test cases (at most 100). Then for each test case, one line with two numbers separated by a blank. Both numbers are four-digit primes (without leading zeros).
Output
One line for each case, either with a number stating the minimal cost or containing the word Impossible.
Sample Input
3
1033 8179
1373 8017
1033 1033
Sample Output
6
7
0

这题比较简单,先打表,把所有四位素数求出来保存
然后就是遍历了,以第一个例子为例:
1033要变成8179,那么我就从素数表里面
把所有和1033只有一位不相同的素数选出来
然后存到set[1]里面,再从素数表里面,把所有和set[1]只有一位不相同的素数存到set[2]里面
每存完第i次,我们就判断一下set[i]里面有没有8179
有的话,我们就输出i就行了
我们遍历素数表的方法其实可以简化到40次
如果从头到尾遍历,需要1000多次,但是我还是从头到尾遍历,因为写起来简单
如果时间超限,我再改成40次的那种,结果一遍就给我过了,哈哈
AC代码:

#include <iostream>
#include <set>
using namespace std;
int prime[2000], num;
bool notprime[10000] = {true, true};
void init()
{
    int i = 2;
    while (i < 10000)
    {
        for (int j = 2 * i; j < 10000; j += i)
            notprime[j] = true;
        i++;
        while (i < 10000 && notprime[i])
            i++;
    }
    for (int i = 1000; i < 10000; i++)
        if (notprime[i] == false)
            prime[num++] = i;
}
int difference(int a, int b)
{
    int n = 0;
    while (a)
    {
        if (a % 10 != b % 10)
            n++;
        a /= 10, b /= 10;
    }
    return n;
}
int main(void)
{
    init(); //打表,把四位数的素数都存在prime数组里面
    int n;
    cin >> n;
    while (n--)
    {
        set<int> step[50]; //用来存遍历结果
        int a, b;
        cin >> a >> b;
        step[0].insert(a);
        if (step[0].count(b))
        {
            cout << 0 << endl;
            continue;
        }
        for (int i = 1; i < 50; i++)
        {
            for (set<int>::iterator it = step[i - 1].begin(); it != step[i - 1].end(); it++)
            {                                 //根据上一步的数据,来计算后面的结果
                for (int j = 0; j < num; j++) //遍历素数表
                {
                    if (difference(*it, prime[j]) == 1) //如果两个四位素数只有一位不相同
                    {
                        step[i].insert(prime[j]); //存起来
                    }
                }
            }
            if (step[i].count(b)) //如果得到了结果
            {
                cout << i << endl; //输出结果
                break;
            }
        }
    }
    return 0;
}

果不其然,我的时间是最慢的,93,哈哈
在这里插入图片描述

G - Mine Sweeper

The game Minesweeper is played on an n by n grid. In this grid are hidden m mines, each at a distinct grid location. The player repeatedly touches grid positions. If a position with a mine is touched, the mine explodes and the player loses. If a positon not containing a mine is touched, an integer between 0 and 8 appears denoting the number of adjacent or diagonally adjacent grid positions that contain a mine. A sequence of moves in a partially played game is illustrated below.在这里插入图片描述
Here, n is 8, m is 10, blank squares represent the integer 0, raised squares represent unplayed positions, and the figures resembling asterisks represent mines. The leftmost image represents the partially played game. From the first image to the second, the player has played two moves, each time choosing a safe grid position. From the second image to the third, the player is not so lucky; he chooses a position with a mine and therefore loses. The player wins if he continues to make safe moves until only m unplayed positions remain; these must necessarily contain the mines.
Your job is to read the information for a partially played game and to print the corresponding board.
Input
The first line of input contains a single postitive integer n <= 10. The next n lines represent the positions of the mines. Each line represents the contents of a row using n characters: a period indicates an unmined positon while an asterisk indicates a mined position. The next n lines are each n characters long: touched positions are denoted by an x, and untouched positions by a period. The sample input corresponds to the middle figure above.
Output
Your output should represent the board, with each position filled in appropriately. Positions that have been touched and do not contain a mine should contain an integer between 0 and 8. If a mine has been touched, all positions with a mine should contain an asterisk. All other positions should contain a period.
Sample Input
8
…*
.



…*…
..

xxx…
xxxx…
xxxx…
xxxxx…
xxxxx…
xxxxx…
xxx…
xxxxx…
Sample Output
001…
0013…
0001…
00011…
00001…
00123…
001…
00123…

扫雷,给出地图,给出我们点了哪些地方,然后输出游戏结果,简单的模拟题
AC代码:

#include <iostream>
using namespace std;
const int maxn = 15;
char Map[maxn][maxn];
char Visited[maxn][maxn];
int n;
char solove(int i, int j)
{
    int ni, nj, ans = 0;
    for (int di = -1; di <= 1; di++)
        for (int dj = -1; dj <= 1; dj++)
        {
            ni = i + di, nj = j + dj;
            if (di == 0 && dj == 0)
                continue;
            if (ni >= 0 && ni < n && nj >= 0 && nj < n && Map[ni][nj] == '*')
                ans++;
        }
    return ans + '0';
}
int main(void)
{
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> Map[i];
    for (int i = 0; i < n; i++)
        cin >> Visited[i];
    bool alive = true;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            if (Visited[i][j] == 'x')
            {
                if (Map[i][j] == '*')
                    alive = false;
                else
                    Visited[i][j] = solove(i, j);
            }
        }
    }
    if (alive == false)
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                if (Map[i][j] == '*')
                    Visited[i][j] = '*';
    for (int i = 0; i < n; i++)
        cout << Visited[i] << endl;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值