2.2数据结构与算法学习日记

目录

洛谷p4387验证栈序列

题目描述

输入格式

输出格式

输入输出样例

 题目分析

代码示例

# [USACO1.5] 八皇后 Checker Challenge

## 题目描述

题目分析

代码示例


洛谷p4387验证栈序列

题目描述

给出两个序列 pushed 和 poped 两个序列,其取值从 1 到 n(n≤100000)。已知入栈序列是 pushed,如果出栈序列有可能是 poped,则输出 Yes,否则输出 No。为了防止骗分,每个测试点有多组数据。

输入格式

第一行一个整数 q,询问次数。

接下来 q 个询问,对于每个询问:

第一行一个整数 n 表示序列长度;

第二行 n 个整数表示入栈序列;

第三行 n 个整数表示出栈序列;

输出格式

对于每个询问输出答案。

输入输出样例

输入 #1复制

2
5
1 2 3 4 5
5 4 3 2 1
4
1 2 3 4
2 4 1 3

输出 #1复制

Yes
No

 题目分析

1.根据题意用栈模拟,首先把a数组进行入栈操作,b数组用来存放出栈序列,注意数据范围

2.当遇到栈顶与b数组元素(出栈序列)相等时开始进行while循环弹栈,如果最后栈为空证明俩序列都相等输出Yes,如果不为空,证明有不相等的元素,输出No

代码示例

#include
using namespace std;
int q,n;
int main()
{
    scanf("%d",&q);
    for(int i=1; i<=q; i++)//有几组数据 
    {
        cin>>n;
        int a[100001],b[100001];
        stacks;
        int h=1;
        for(int j=1; j<=n; j++)
        {
            cin>>a[j];
        }
        for(int j=1; j<=n; j++)
        {
            cin>>b[j];
        }
        for(int k=1; k<=n; k++)//把a数组入栈依次去跟b数组里的元素相判断 
        {
            s.push(a[k]);
            while(s.top()==b[h])//当栈顶与b数组里的元素相等时弹栈,h自增 
            {

                s.pop();
                h++;
                if(s.empty())break;
            }
        }
        if(s.empty())cout<<"Yes"<

 

# [USACO1.5] 八皇后 Checker Challenge

## 题目描述

一个如下的 $6 \times 6$ 的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。

2.2数据结构与算法学习日记_第1张图片

上面的布局可以用序列 $2\ 4\ 6\ 1\ 3\ 5$ 来描述,第 $i$ 个数字表示在第 $i$ 行的相应位置有一个棋子,如下:

行号 $1\ 2\ 3\ 4\ 5\ 6$

列号 $2\ 4\ 6\ 1\ 3\ 5$

这只是棋子放置的一个解。请编一个程序找出所有棋子放置的解。  
并把它们以上面的序列方法输出,解按字典顺序排列。  
请输出前 $3$ 个解。最后一行是解的总个数。

## 输入格式

一行一个正整数 $n$,表示棋盘是 $n \times n$ 大小的。

## 输出格式

前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。

## 样例 #1

### 样例输入 #1

```
6
```

### 样例输出 #1

```
2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4
```

## 提示

【数据范围】  
对于 $100\%$ 的数据,$6 \le n \le 13$。

题目翻译来自NOCOW。

USACO Training Section 1.5

题目分析

1.根据题目要保证每个棋子所在的位置的对角线和行还有列上只有它一个棋子,所以当棋子走时它的列和对角线上有重复的已经标记为走过的时,此时就不能走,得换下一个位置

2,用一个函数来单独标记列和俩个对角线,并把当时可以走的列坐标赋给一个答案数组里,此时无论如何答案数组里的肯定是能走的列坐标

3.注意只输出前三个,得用个变量来累加到三,表示答案输出结束,递归终止

代码示例

#include
using namespace std;
int m1[30],m2[30],m3[30],ans[30],sum,n;
void setvalue(int x,int y,int z)
{
   if(z==1) ans[x]=y;//存放可以走的列号,以便输出 
    m1[y]=z;//标记列 
    m2[x+y]=z;//标记副对角线(从左下到右上) 
    m3[x-y+n]=z;//标记主对角线 (从左上到右下) 
}
void dfs(int step)
{
    if(step>n)
    {
        sum++;
        if(sum<=3){for(int i=1; i<=n; i++)cout<>n;
    dfs(1);
    cout<

如以上有任何知识性的问题,还请各位大佬指点一二

你可能感兴趣的:(学习,算法,数据结构)