2021.01.27刷题总结

B - 愚人节的礼物

四月一日快到了,Vayko想了个愚人的好办法——送礼物。嘿嘿,不要想的太好,这礼物可没那么简单,Vayko为了愚人,准备了一堆盒子,其中有一个盒子里面装了礼物。盒子里面可以再放零个或者多个盒子。假设放礼物的盒子里不再放其他盒子。

用()表示一个盒子,B表示礼物,Vayko想让你帮她算出愚人指数,即最少需要拆多少个盒子才能拿到礼物。

Input

本题目包含多组测试,请处理到文件结束。

每组测试包含一个长度不大于1000,只包含’(’,’)'和’B’三种字符的字符串,代表Vayko设计的礼物透视图。
你可以假设,每个透视图画的都是合法的。

Output

对于每组测试,请在一行里面输出愚人指数。
Sample Input

((((B)()))())

(B)

Sample Output

4

1

这题应该是想考察我们对的基本用法,因为之前做过一个括号匹配问题,用栈解的。
不过这个题目,不用那么麻烦因为数据都是合法的,所以根据这一特性:
我们只需要判断B前面有多少个字符,然后减去B前面成对的括号数量就行了,不需要什么栈进栈出那么复杂:
AC代码:

#include <bits/stdc++.h>
using namespace std;
int main(void)
{
    string str;
    while (cin >> str)
    {
        int ans = str.find('B');
        ans -= 2 * count(str.begin(), str.begin() + ans, ')');
        cout << ans << endl;
    }
    return 0;
}

水题一个。

E - 棋盘问题

在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。

Input

输入含有多组测试数据。

每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <=
n

当为-1 -1时表示输入结束。

随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。

Output

对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。

Sample Input

2 1

#.

.#

4 4

…#

…#.

.#…

#…

-1 -1

Sample Output

2

1

N皇后问题的简化版,因为只需要判断行和列有没有棋子就行了。
因为每行每列最多只能有一个棋子,所以我们每行只放一个,就能保证行只有一个棋子,然后在放的时候判断放棋子的那一列有没有棋子,如果有就不能放没有的话就放
AC代码:

#include<iostream>
using namespace std;
const int maxn = 10;
int n, k, ans;
void fun(char m[][maxn], int N, int K)
{
    if (K == k) //棋子都放完了
    {
        ans++;
        return;
    }
    if (N == n + 1)
        return;
    for (int j = 1; j <= n; j++) //遍历第N行
    {
        if (m[N][j] == '#') //是棋盘区
        {
            int i;
            for (i = 1; i < N; i++) //遍历列,我们一行只放一个棋子
                if (m[N - i][j] == 'o')//判断第j列有没有棋子
                    break; 
            if (i == N)    //m[N][j]的地方能放棋子
            {
                m[N][j] = 'o';        //放棋子
                fun(m, N + 1, K + 1); //进入下一行
                m[N][j] = '#';        //回溯,把棋子取回
            }
        }
    }
    fun(m, N + 1, K);//不放棋子,进入下一行
}
int main(void)
{
    while (cin >> n >> k)
    {
        if (n <= -1 && k <= -1)
            break;
        //
        char m[maxn][maxn] = {0};
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                cin >> m[i][j];
        //
        ans = 0;
        fun(m, 1, 0);
        cout << ans << endl;
    }
    return 0;
}

D - N皇后问题

在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。

输入值

共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。 输出量

共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。

样本输入

1

8

5

0

样本输出

1

92

10

这题的思路也比较简单
①我们每行只放一个皇后,就能保证一行里面只能有一个
②判断某个格子能不能放,要满足两个条件:
一、格子所在列不能有皇后
二、左上角和右上角方向不能有皇后
图解
假设有一个8*8的棋盘
在这里插入图片描述
①其中黄色格子代表已经放了皇后,图上的第一行到第三行都按照规则放了皇后。
②现在我们在判定第四行那个黑色格子能不能放。
③按照规则,我们只需要判断黑色格子所在列、左上和右上方向的格子有没有皇后就行了,即那些绿色格子(第四行下面的棋盘不需要考虑,因为我们没放)。
④黑色格子明显可以放皇后,所以我们放一个皇后。
⑤然后开始判定第五行的皇后,就按照这个过程一直放下去,就能得到答案。
然后说一下,因为题目只要求我们计算1~10阶的棋盘,所以我们可以先打表,把所有答案全都计算出来,我昨天一次一次的来,时间超限了。
AC代码

#include <stdio.h>
#define maxn 15
int ans, count;
void fun(bool a[][maxn], int N, int n)
{
    int i, j;
    if (n == N)
    {
        // for (i = 0; i < N; i++)
        // {
        //      for (j = 0; j < N; j++)
        //              printf("%d ", a[i][j]);
        //      printf("\n");
        // }
        // printf("\n");
        ans++;
        return;
    }
    for (i = 0; i < N; i++) //遍历列
    {
        for (j = 1; j <= n; j++) //遍历行
        {
            count++;
            //一行只放一个皇后,所以不需要判断行
            if (a[n - j][i] == true) //判断第i列有没有皇后,只需要判断[0,n]行的列,因为我们只放到了第n行
                break;
            if (i >= j && a[n - j][i - j] == true) //判断a[n][i]左上角方向有没有皇后
                break;
            if (i + j < N && a[n - j][i + j] == true) //判断a[n][i]右上角方向有没有皇后
                break;
        }
        if (j == n + 1) //如果a[n][i]所在的列、左右上角方向,都没有皇后
        {
            a[n][i] = true;   //就可以在a[n][i]的位置放一个皇后
            fun(a, N, n + 1); //然后开始放n+1行的皇后
            a[n][i] = false;  //回溯的时候,再把n行的皇后拿掉
        }
    }
    return;
}

int main(void)
{
    int answer[11];
    for (int i = 1; i <= 10; i++)
    {
        bool a[maxn][maxn] = {false};
        ans = 0;
        fun(a, i, 0);
        answer[i] = ans;
    }
    int N;
    while (scanf("%d", &N) != EOF)
    {
        if (N <= 0)
            break;
        printf("%d\n", answer[N]);
    }
}

A - ACboy needs your help again!

ACboy was kidnapped!!

he miss his mother very much and is very scare now.You can’t image how
dark the room he was put into is, so poor 😦.

As a smart ACMer, you want to get ACboy out of the monster’s labyrinth.But when you arrive at the gate of the maze, the monste say :" I have heard that you are very clever, but if can’t solve my problems, you will die with ACboy."

The problems of the monster is shown on the wall:

Each problem’s first line is a integer N(the number of commands), and a word “FIFO” or “FILO”.(you are very happy because you know “FIFO” stands for “First In First Out”, and “FILO” means “First In Last Out”).

and the following N lines, each line is “IN M” or “OUT”, (M represent a integer).

and the answer of a problem is a passowrd of a door, so if you want to rescue ACboy, answer the problem carefully!

Input

The input contains multiple test cases.

The first line has one integer,represent the number oftest cases.

And the input of each subproblem are described above.

Output

For each command “OUT”, you should output a integer depend on the word is “FIFO” or “FILO”, or a word “None” if you don’t have any integer.
Sample Input
4
4 FIFO
IN 1
IN 2
OUT
OUT
4 FILO
IN 1
IN 2
OUT
OUT
5 FIFO
IN 1
IN 2
OUT
OUT
OUT
5 FILO
IN 1
IN 2
OUT
IN 3
OUT
Sample Output
1
2
2
1
1
2
None
2
3

就考察一下栈和队列的最基本的知识,简单的模拟题
队列:先进先出
栈:先进后出
AC代码:

#include <bits/stdc++.h>
using namespace std;
int main(void)
{
    int t;
    cin >> t;
    while (t--)
    {
        int n;
        string type;
        cin >> n >> type;
        string means;
        int data;
        if (type == "FIFO")
        {
            queue<int> que;
            for (int i = 0; i < n; i++)
            {
                cin >> means;
                if (means == "IN")
                {
                    cin >> data;
                    que.push(data);
                }
                else if (means == "OUT")
                {
                    if (que.size())
                    {
                        cout << que.front() << endl;
                        que.pop();
                    }
                    else
                        cout << "None" << endl;
                }
            }
        }
        else if (type == "FILO")
        {
            stack<int> que;
            for (int i = 0; i < n; i++)
            {
                cin >> means;
                if (means == "IN")
                {
                    cin >> data;
                    que.push(data);
                }
                else if (means == "OUT")
                {
                    if (que.size())
                    {
                        cout << que.top() << endl;
                        que.pop();
                    }
                    else
                        cout << "None" << endl;
                }
            }
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值