11.13知识整理

断更了一周今天重新更起来!!

1.暴力枚举

题目描述

有一个 n×m 方格的棋盘,求其方格包含多少正方形、长方形(不包含正方形)。

输入格式

一行,两个正整数 n,m(n≤5000,m≤5000)。

输出格式

一行,两个正整数,分别表示方格包含多少正方形、长方形(不包含正方形)。

——————————————————————————————————————

思路:这是一个暴力枚举的题,遇到这种题可以先把他当作一个简单的小学数学题来做,如果数学题你模拟除了这个样例来,说明你就是可以成功的将这题做出来,

1.正方形,这个咱们可以用边长来实现,边长为1的几个,2的几个总结出规律之后将他们乘起来即可

11.13知识整理

如同这个图,2个格子的正方形就是长可以划分4个依次类推第i格时是划分n-i+1,宽就是m-i+1。

2.长方形

这个就更简单了,就是以此类推一个能划分几个,最后得出来与正方形一样的结论,只不过多了一个长与宽

注意!

正方形的边长不能超过a与b的最小值,因为两个边是相等的

在长方形时,要注意如果枚举的i>j时要直接continue,因为题目描述中长方形是不包括正方形的

还有数据类型n,m最好使用longlong,5000乘5000很容易就爆掉,保险起见使用longlong

———————————————————————————————————————————

代码呈现:

#include <iostream>
using namespace std;
int main(){
    long long s=0,z=0;
    long long n,m;
    cin>>n>>m;
    for(int i=1;i<=min(n,m);i++)
    {
        s+=(n-i+1)*(m-i+1);
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i==j)
            continue;
            z+=(n-i+1)*(m-j+1);
        }
    }
    cout<<s<<" "<<z;
}


——————————————————————————————————————————

 2.全排列问题

题目描述

按照字典序输出自然数 1 到 n 所有不重复的排列,即 n 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。

输入格式

一个整数 n。

输出格式

由 1∼n 组成的所有不重复的数字序列,每行一个序列。

每个数字保留 5 个场宽。

————————————————————————————————————————

思路解析:这是一个非常简单的dfs算法,但是这个全排列问题在排序之后就会全部输出,所以此

函数不需要返回值,是void类型,dfs都是通过递归来实现的,因为要不断地来回搜索,所以要判

断在递归结束的瞬间,就是判断函数的结束,所以是顺序是从0开始的,所以是n-1的时候排完,如

果到了n说明就已经排完了,直接输出即可,但是也要从0开始,但是在下面就要从1开始了,因为

在题目中0不参加排序,之后要用到一个小技巧就是洪水淹没,要定义一个st数组,判断每个数的

状态,用过了记作1,没有的话就是0,数组刚开始都是默认定义为0,只需要判断st[i]在if条件里即

可,因为只要非0的都是真,0说明没有用过,所以让a[t]=i,一开始只传入一个参数,表示杠开始

进行排列的数但是最后要恢复现场,避免到后来没法再列举其他情况。所以要在a[t]=i,之后让

st[i]=1,之后再return没有返回值只写return即可,再后面定义让st[i]再为0,之后因为要从0开始进行

排列所以在main函数中需要直接调用dfs(0)即可

注意!!

1.题目里提到要保留五个长宽,意思就是如果不到五位就要将他补上,所以我们这里利用printf

只要是整数就是%d,补上就是%5d就可以了,最后每输出一个要换行,还要加一个puts里面什么

都不加

———————————————————————————————————————————

代码

#include<iostream>
using namespace std;
int a[10],st[10];
int n;
void dfs(int t)
{
    if(t==n)
    {
    for(int i=0;i<n;i++)
    {
     printf("%5d",a[i]);
     
    }
    puts("");
    return;
    }
    for(int i=1;i<=n;i++)
    {
        if(st[i]!=0)
        {
           continue;

        }
        a[t]=i;
        st[i]=1;
        dfs(t+1);
        st[i]=0;
    }
}
int main()
{
   cin>>n;
   dfs(0);
   return 0;
}

注意!!!!

dfs是通过递归实行的,在结束时一定要递归调用

不要在for循环里puts,这样会输出亿点换行

要先输出方案再结束,不能调换顺序,在for循环里进行要用continue if里面。

———————————————————————————————————————————

上一篇:Promise的构造函数方法


下一篇:promise