当前位置: 首页 > news >正文

漯河网站建设(千弘网络)企业网站有哪些类型

漯河网站建设(千弘网络),企业网站有哪些类型,长沙企业网站开发哪家专业,山西第二波疫情最新消息【前情提要】 此文章包含洛谷题单的枚举题单,共14题,本篇7道题,主要分析思路,并通过这几道题目,进行总结有关枚举的内容。所以内容比较多,可以先收藏起来,慢慢看。 题单链接:暴力枚…

【前情提要】

此文章包含洛谷题单的枚举题单,共14题,本篇7道题,主要分析思路,并通过这几道题目,进行总结有关枚举的内容。所以内容比较多,可以先收藏起来,慢慢看。

题单链接:暴力枚举https://www.luogu.com.cn/training/108

题目1

分析1

在一个n行m列的棋盘里,找一共有多少正方形和长方形。

而正方形和长方形都属于矩形,区别只有长宽长度的问题,那么可以一并按照矩形分析,当长宽相等时是正方形,否则是长方形。

再接着想,该如何算出棋盘里有多少矩形呢?

首先假设是一个1x2的矩形,把它当作一块积木,放入棋盘中,那么它可以横着放,也可以竖着放。

1. 当它横着放,一共有多少种可能性?(假设棋盘长为n,宽为m)

  • 当我们只关注宽时——发现一共有m-1个长度为2的地方,
  • 当只关注长时——一共有n个长度为1的地方

最终结果为n*m-1

2. 而竖着放同理。

我们可以大胆猜测,长为a宽为b的矩形一共有(n-a+1)*(m-b+1)

那么我们为了更保险一些,再举个例子,假设求3x3矩形的个数

1. 当它横着放,一共有多少种可能性?(假设棋盘长为n,宽为m)

  • 当我们只关注宽时——发现一共有m-2个长度为3的地方,
  • 当只关注长时——一共有n-2个长度为3的地方

最终结果为(n-2)*(m-2)

2. 由于是正方形,不需要看竖着的情况

基本正确,为了更严谨一些,可以再尝试举出类似例子。

那根据这个思路,我们可以进一步写出代码,注意范围,那么谈到范围时,我们就要想到假如横着竖着去考虑的话,从横着的1x2到竖着的2x1,假设长方向的设为i,宽方向的设为j

那么对应着i=1,j=2和i=2,j=1,两种情况

而i的范围为从1到n,j的范围为1到m,只需要在里面遍历就可以出现上面这两种情况,所以不需要再多考虑。

代码1

#include<bits/stdc++.h>using namespace std;long long ans,res;int main()
{int n,m;scanf("%d %d",&n,&m);for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(i==j)//正方形{ans+=(n-i+1)*(m-i+1);}else{res+=(n-i+1)*(m-j+1);//求长方形,长宽方向已固定,所以不需要看纵向和横向结果  }}}cout << ans << " " << res << endl;return 0;
}

总结1

这题的核心点在于如何求出矩形数量,通常情况下可以多多列举几个例子,去分析,然后推出整体的公式。

题目2

对于 100% 的数据,n≤5000。 

分析2

题目意思是给你一个数字m,把10个数字(每个数字范围为1到3)的加和变成这个数字,并输出方案数和具体方案内容。

显而易见10个循环是不行的,超出时间复杂度了。

所以只能另辟蹊径。

用dfs(也就是深度优先遍历)

不懂的可以先看这篇(觉得麻烦也可以不看,下面会简单说明)——dp_背包问题(涉及dfs分析,记忆化搜索)_固定背包体积装物品总价值最大,运筹学问题-CSDN博客

只需要看dfs的部分即可

简单来说,就是先假设第一个数字为1,在这个基础上有三种选择,第二个数字有可能是1,2,3,我们先选择1再进行考虑第三个数字,直到考虑完10个数字.

假设最后结果为m则算是一种方案(然后遍历输入?),回溯到考虑第十个数字,这里我们选择2。

如果结果不为m,则这种方案不算,要去考虑第十个数字,选择2。

理论成立,下面就是代码了。

代码2

#include<iostream>
#include<algorithm>
#include<cstring>using namespace std;const int N=1e5+10;
int a[N][11],s[11];
int n;
int res;void dfs(int x,int p){if(x==10){if(p!=n){return;}for(int i=0;i<10;i++){a[res][i]=s[i];}res+=1;return;}s[x]=1;dfs(x+1,p+1);s[x]=2;dfs(x+1,p+2);s[x]=3;dfs(x+1,p+3);return;
}int main(){scanf("%d",&n);dfs(0,0);//0表示调料的总克数cout<<res<<endl;for(int i=0;i<res;i++){for(int j=0;j<10;j++){printf("%d ",a[i][j]);}printf("\n");}return 0;
}

总结2

这是一道简单的dfs题,按照正常递归思路思考回溯即可

题目3

分析

9个数字,组合成三个数A,B,C,满足一定的比例关系。

那么假如我们已经知道了A,则可以根据比例求出B和C,再去判断满足不满足每个数字只在A,B,C,中出现且仅出现一次的条件。

那么怎么去实现呢?

1. A是怎么遍历的

2. 怎么判断每个数字在A,B,C中有且仅出现一次

首先,A是由1到9这几位数字中抽出三个数字组合而成的。

A的第一位有9种可能性,第二位有除了第一位以外的其余8种可能性,第三位有7种可能性

假设我们嵌套遍历——A的每一位数字,把A弄出来之后,再计算B和C,再设置变量存储B和C的每一位数字,确保每一位都不相等——则输出A,B,C

假如没有输出(可以借用bool变量判断,刚开始定义为false如果输出了则该变量等于true,最后根据这个看是否输出No!!!)则输出No!!!

代码

#include<bits/stdc++.h>using namespace std;int main()
{double a,b,c;bool f=false;cin>>a>>b>>c;if(a==b||a==c||b==c){cout<<"No!!!";return 0;}b/=a;c/=a;for(int i=1;i<10;i++){for(int j=1;j<10;j++){for(int k=1;k<10;k++){if(i!=j&&i!=k&&j!=k){int n1=i*100+j*10+k;int n2=n1*b;int s1=n2%10;int s2=n2%100/10;int s3=n2/100;if(s1!=s2&&s1!=s3&&s2!=s3&&s1!=i&&s1!=j&&s1!=k&&s2!=i&&s2!=j&&s2!=k&&s3!=i&&s3!=j&&s3!=k&&n2<1000&&s1!=0&&s2!=0&&s3!=0){int n3=n1*c;int p1=n3%10;int p2=n3%100/10;int p3=n3/100;if(p1!=p2&&p1!=p3&&p2!=p3&&p1!=i&&p1!=j&&p1!=k&&p1!=s1&&p1!=s2&&p1!=s3&& p2!=i&&p2!=j&&p2!=k&&p2!=s1&&p2!=s2&&p2!=s3&& p3!=i&&p3!=j&&p3!=k&&p3!=s1&&p3!=s2&&p3!=s3&&n3<1000&&p1!=0&&p2!=0&&p3!=0){cout<<n1<<" "<<n2<<" "<<n3<<endl;f=true;}}}}}}if(!f){cout<<"No!!!";}return 0;
}

总结

这题主要是分析,分析出来如何做的写代码就简单了

题目4

分析

题目意思是给你n个数,从中选k个,加和,判断和是否为素数,如果是则种类加1

那么这题代码主要点在于——1. 从n个数中选k个,2 判断和是否为素数

分别考虑如何实现

1. 从n个数中选则k个,首先可以用for循环遍历取得k位数字,也可以用dfs函数,把n个数填在k个格子里面,每个数只能用一次。

2. 判断是否为素数,单开一个函数即可,从素数的定义入手,素数是指从1到本身,它只能%1和它本身时==0,为了简便,可以把范围从sum缩小到sqrt(sum)

理论上我们已经分析出做法了,那么下面就是具体的实施了

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>using namespace std;int a[21];
int k,res,n,flag;
//bool s[21];
int startid;bool issu(int p)
{if (p < 2) return false;for (int i = 2; i <= sqrt(p); i++) {if (p % i == 0) return false;}return true;
}void dfs(int x)
{if(x==k){if(issu(res)){flag++;}return;}else{int start=startid;for(int i=start;i<n;i++){res+=a[i];startid=i+1;dfs(x+1);res-=a[i];startid=start;}}
}
int main()
{cin>>n>>k;for(int i=0;i<n;i++){cin>>a[i];}dfs(0);cout<<flag<<endl;return 0;
}

总结

代码中有个重要的点——》就是在dfs中如何防止元素重复,也就是这个元素用过了,如何防止下次不再用。我们把这部分的代码拿出来分析

首先定义了

int start=startid;
for(int i=start;i<n;i++)
{res+=a[i];startid=i+1;dfs(x+1);res-=a[i];startid=start;
}//把dfs函数参数设置为三个
void dfs(int e,int sum,int x)//x表示下一回的开始
{if(e==k){if(isPrime(sum)){res++;}return;}for(int i=x;i<n;i++){dfs(e+1,sum+s[i],i+1);//下一回从i+1开始}return;
}

 这个部分建议记忆,在很多题目中也可能会用到。

题目5

分析

这个题说的是从n个元素中抽出r个元素,输出所有组合,(格式是每个组合数字要占三个字符,用到setw(),或者直接用printf格式化输出)

我们来看如何去写,

依旧是假设有r个位置,要把n个元素不重复的填入进去,每个位置有多种选择,可以用dfs来实现

代码(dfs)

#include<iostream>
#include<algorithm>
#include<iomanip>using namespace std;const int N=21;
int s[N];
int n,r;void dfs(int e,int f,int x)
{if(e==r){for(int i=0;i<r;i++){cout<<setw(3)<<s[i];}cout<<endl;return;}for(int i=f;i<r;i++){for(int j=x;j<=n;j++){s[i]=j;if(s[i-1]<s[i]){dfs(e+1,f+1,j+1);//s[i]=0;//为什么不用还原?因为下一次会被覆盖}}}
}int main()
{scanf("%d%d",&n,&r);dfs(0,0,1);return 0;
}

总结

这个依旧用到了上个问题的不重复写入的方法,但这道题目和上一题不一样的是它需要把每次的结果存入数组中,所以需要再加一个for循环,但是为了不让数组每次遍历都从头开始,再设置一个参数,表示数组的位置。

题目6

分析

这题就是直接给你一共数,输出1到这个数的全排列。

有两种方法

1. 调用库函数next_permutation

2. 自己手写全排列函数

根据这个方法,我们依次分析一下

1. 库函数next_permutation(),里面传入两个参数,第一个是数组的首地址,第二个是数组的末地址,和sort函数差不多,它返回这个数组的下一个全排列

2. 假如自己手写全排列函数,相当于有n个位置,要把n个数填入这几个位置上,每个位置有不止一种选择,用dfs来实现,和上一题差不多,但比那个要简单一些

注意,输出时的元素要占5个位置,用上一题的setw()函数,记得写头文件#include<iomanip>

代码(next_permutation)

#include<iostream>
#include<algorithm>
#include<iomanip>using namespace std;int main()
{int n,l=1;scanf("%d",&n);int s[n];for(int i=1;i<=n;i++){s[i]=i;l*=i;}//全排列一共n!种for(int i=1;i<=l;i++){for(int j=1;j<=n;j++){cout<<setw(5)<<s[j];}cout<<endl;next_permutation(s+1,s+n+1);}return 0;
}

 

代码(dfs)

#include<bits/stdc++.h>using namespace std;int s[10];
bool a[10];
int n;
int res=1,ans;void dfs(int e)
{if(e>n){for(int i=1;i<=n;i++){cout<<setw(5)<<s[i];}cout<<endl;return;}for(int i=1;i<=n;i++){if(!a[i]){a[i]=true;s[e]=i;dfs(e+1);a[i]=false;}}
}int main()
{scanf("%d",&n);int m=n;while(m!=1){res*=m;m--;}dfs(1);return 0;
}

总结

这里用了另一种防止填入数字重复的方法,只需要定义一个长度和int数组一样大的布尔数组,初始值为false,如果没用过了则可以把它存入int数组并,并更新为true,遍历下一个dfs,同时回溯把刚才的true变为false

题目7

 

分析

这个题目稍微有些复杂,就是说会给你n个数字,以及要在这个数字组合成的外星文上加的数

主要问题在于如何把这n个数字加m后变成另外n个数字,这个过程是怎样运作的

我们主要观察这个部分:

这是只有三个手指的时候,相当于123的全排列,而且是按照顺序的,所以很自然地想到了用全排列那题的方法,next_permutation()

代码

#include<bits/stdc++.h>using namespace std;int main()
{int n,m;scanf("%d",&n);scanf("%d",&m);int a[n];for(int i=0;i<n;i++){scanf("%d",&a[i]);}for(int i=1;i<=m;i++){next_permutation(a,a+n);}for(int i=0;i<n;i++){printf("%d ",a[i]);}return 0;
}

总结

这题主要是刚开始不太好想到,要善于观察那手指的数字,从中发现规律。 

http://www.cadmedia.cn/news/14857.html

相关文章:

  • 国家企业信用网企业查询优化优化
  • 外汇返佣网站建设株洲seo优化
  • 微信推广方案范文深圳sem优化
  • 给我播放电影在线观看电脑系统优化软件十大排名
  • 做网站 教程网页设计案例
  • 舆情系统排名seo外包公司报价
  • 建立网站的意义网络营销推广是做什么的
  • 南京网站建设公司 w网络平台销售
  • 国内哪家公司做网站最好seo交流群
  • 宿州房地产网站建设临沂做网站的公司
  • 抖音小程序平台杭州优化建筑设计
  • 建设手机网站包括哪些费用百度如何推广产品
  • dw网页设计官网重庆电子商务网站seo
  • 建企业网站一般多少钱免费seo公司
  • 基于p2p的网站建设湖南关键词优化推荐
  • 腾讯云服务器免费领取试用自己怎么做网站优化
  • 如何做好品牌网站建设简述企业网站推广的一般策略
  • 模板网站建设代理商网络营销的内容
  • 专业制作藏品网站seo推广岗位职责
  • 全景网站是怎么做的安徽360优化
  • 杭州网站建设公司如何让网站被百度收录
  • 贵州今天疫情新增消息厦门站长优化工具
  • 站群cms源码品牌推广软文案例
  • 对网站建设行业的了解最新新闻
  • 手机网站开发成本英文网站设计公司
  • 全网霸屏推广营销系统seo分析网站
  • 企业网站推广和营销网页推广区别seo关键词怎么填
  • 网站开发商临沧seo
  • 毕业论文做网站在线注册免费域名
  • 小学门户网站建设搜索引擎优化包括