枚举与尺取法(蓝桥杯 c++ 模板 题目 代码 注解)_蓝桥杯大赛c c+(1)

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

calc(1);//从一开始

}


![](https://img-blog.csdnimg.cn/direct/6f4a9da7f7eb43bd8609ddefe131fd1c.png)


## 题目一(公平抽签 排列组合):


##  代码:



#include
#include
using namespace std;
int n, m;
vector chosen;
vector name;
void calc(int k)
{
if (chosen.size() > m || chosen.size() + (n - k + 1) < m)//选多了或者选少了,chosen.size()表示选了几个
return;
if (k == n + 1)//最后一个也已经选完了
{
for (int i = 0; i < chosen.size(); i++)
cout << name[chosen[i]-1] << " ";
cout << endl;
}
chosen.push_back(k);//选数字k
calc(k + 1);//继续往深度遍历
chosen.pop_back();//不选数字k
calc(k + 1);//继续往深度遍历
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)
{
string s;
cin >> s;
name.push_back(s);
}
calc(1);
}


## 题目二(座次问题 全排列):


![](https://img-blog.csdnimg.cn/direct/db856675b84241dbbf049ecc92659e2a.png)


## 代码:



#include
#include
using namespace std;
int n;
int chosen[15];
int book[15];//标记是否访问过
string name[15];
void calc(int k)
{
if (k == n + 1)//最后一个数都已经选完了
{
for (int i = 1; i <= n; i++)//输出该排列
{
cout << name[chosen[i] - 1] << " ";//name下标从0开始
}
cout << endl;
return;
}
for (int i = 1; i <= n; i++)
{
if (book[i])//标记是否用过
continue;
book[i] = 1;//标记为用了
chosen[k] = i;//第k个为数字i
calc(k + 1);//继续往深度遍历
book[i] = 0;//回溯,没访问过i
chosen[k] = 0;
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> name[i];
}
calc(1);//从第一个开始
}


## 题目三(排列序数):


![](https://img-blog.csdnimg.cn/direct/37cf80aff35c4a2db187858e54c82ab7.png)


## 代码:


![](https://img-blog.csdnimg.cn/direct/81c50612d88946d98b59adc7d28b81cd.png) 



#include //用next_permutation函数进行全排列
#include
using namespace std;
int main()
{
long long cnt=0;//记录个数
string s;
string s1;
cin >> s;
s1 = s;
sort(s.begin(), s.end());//从大到小排序
do {
if (s == s1)//相等的时候跳出
break;
cnt++;
} while (next_permutation(s.begin(), s.end()));//开始遍历
cout << cnt;

}



> 
> 尺取法是一种线性的高效率算法。记(L,R)为一个序列内以L为起点的最短合法区间,如果R随L的增大而增大的,就可以使用尺取法。具体的做法是不断的枚举L,同时求出R。因为R随L增大而增大,所以总时间复杂度为O(n)
> 
> 
> 


## 题目四( 美丽的区间 尺取法):


![](https://img-blog.csdnimg.cn/direct/2017e34c9b73482a9691d7aa64b053a9.png)


## 代码:



#include
using namespace std;
int n, s;
int ans = 1e8, sum = 0;
int a[100010];
int main()
{
cin >> n >> s;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int l = 1, r = 1; r <= n; )
{
if(sum<s)//不大于s,则加上,往右遍历
{
sum+=a[r],r++;
}
else
{
ans=min(r-l,ans);//取小的
sum-=a[l];//减掉最左边
l++;//往下遍历
}
}
if (ans == 1e8)//不存在
cout << 0;
else
cout << ans;
}


##  题目五(奇怪的动物园 尺取法):


![](https://img-blog.csdnimg.cn/direct/4a5ec1647c434f999b346c780fb8c6e5.png)


## 代码:



#include
using namespace std;
int n, m, cnt,ans,ansl=0,ansr=0;//ans记录票价
int a[1010];
int b[1010];//记录x类动物的数量
void In(int x)
{
if (b[x] == 0) cnt++;//之前没有x类动物,现在加入了,种类cnt++
b[x]++;//x类动物数量加一
}
void De(int x)
{
if (b[x] == 1) cnt–;//之前有一个x类动物,现在删掉,种类cnt–
b[x]–;//x类动物数量减一
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> a[i];

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值