专栏推荐
我的专栏------
专栏链接
1.文章平均质量分 70分以上
2.以洛谷题为基础,解决C++问题
3.有题目、讲解、思路、参考代码......
- 文章数:29 (2024.3.8)
课前C++小程序(脱控极域电子教室)
这个图标相信现在的学生党没有人想看到
而且每个人都想干掉这款软件,
今天,喷火龙廖 就来聊一下,如何脱控极域电子教室。
那到底该咋做捏?
正片开始
作为编程博主,不如咱先用C++写一遍,看看行不行
cpp
#include<bits/stdc++.h>
#include<windows.h>
using namespace std;
int main(){
Sleep(1000);
system("TASKKILL /F /IM StudentMain.exe /T");
return 0;
}
亲测有效,推荐指数:
缺点:紧要关头没有时间编译运行😑
卡BUG(绝对成功)
同样,召唤出粘滞键,
用鼠标摁住这个界面(不要松),同时按Win+Tab
将粘滞键界面关掉,再次按Win+Tab ,并按两下Win键,回到极域界面,会弹出极域崩溃的提示,按退出即可,
亲测有效,推荐指数:
提示
不会用洛谷的可以看看这篇文章------洛谷使用指南
还有,以下链接是题目的链接。
P1036 [NOIP2002 普及组] 选数
题目描述
已知 n 个整数 1,2,⋯ ,x1,x2,⋯,xn,以及 11 个整数 k(k<n)。从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。例如当 n=4,k=3,4 个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为:
3+7+12=22
3+7+19=29
7+12+19=38
3+12+19=34
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数:3+7+19=29。
输入格式
第一行两个空格隔开的整数 n,k(1≤n≤20,k<n)。
第二行 n 个整数,分别为 1,2,⋯ ,x1,x2,⋯,xn(1≤xi≤5×106)。
输出一个整数,表示种类数。
输入输出样例
输入 #1
4 3
3 7 12 19
输出 #1
1
解题思路
这个题我也是卡了好久,看书的时候突然想到用深度搜索很适合解这道题。 我设置的变量是
- i,代表第i个数
- nums,代表已经加了几个数
- sum,加了nums个数之后的总和
- ans,要输出的答案,初始化为0
dfs函数如下:dfs(i,nums,sum) 思路是,在面对第i个数时,我们有两种选择,一个是加第i个数,一个是不加第i个数,加的话,我们就把i+1(处理下一个数),sums+1,sum+num[i]放到dfs里递归,不加的话,就把i+1(还是要处理下个数),nums,sum(不用动,因为没有加第i个数)放到dfs里递归。
还有限制条件,如果nums==k时,就代表已经加了k个数,此时检测sum是否是素数,如果是的话,ans++。
还有i要小于等于n。
AC
cpp
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
constexpr int N=25;
int n,k,z=0,s[N],st[N],sum=0,ans=0;
bool pd(int n){
for(int i=2;i*i<=n;i++){
if(n%i==0){
return false;
}
}
return true;
}
void dfs(int u,int sum,int start){
if(u==k){
if(pd(sum))
ans++;
return;
}
for(int i=start;i<n;i++) {
dfs(u + 1, sum + s[i], i + 1);
}
return;
}
int main(){
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++){
scanf("%d",&s[i]);
}
dfs(0,0,0);
printf("%d\n",ans);
return 0;
}
P1706 全排列问题
题目描述
按照字典序输出自然数 1 到 n 所有不重复的排列,即 n 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。
输入格式
一个整数 n。
输出格式
由 1∼n 组成的所有不重复的数字序列,每行一个序列。
每个数字保留 55 个场宽。
输入输出样例
输入 #1
3
输出 #1
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
说明/提示
1≤n≤9。
解题思路
我是用搜索来做的
a数组是用来存放当前选择的排列顺序,b数组则是用来判断当前数是否在a数组中
出现过(其中1表示出现过,0表示未出现过).
本题解思路是这样的:
按1~n的顺序枚举第i位(用搜索来过渡),再逐个判断1~n中哪个数是当前序
列没有出现过的------如果出现过,则将它存储到a数组中,继续下一位的枚举;否
则就继续下一个数的枚举.当第n位枚举完1~n时,就可以直接输出a数组.完事后,
再退回上一位,如果上一位也枚举完1~n后,就再继续退回;如果未枚举完,则把
a的当前位置清空,把b[i]的数变成0(就是代表没有出现过).
最后,如果n位都枚举完1~n之后,就可以stop了...
AC
cpp
#include<bits/stdc++.h>
using namespace std;
int a[10],n;
bool vis[10];
void dfs(int u){
if(u>n){
for(int i=1;i<=n;i++){
cout<<setw(5)<<a[i];
}
cout<<endl;
return;
}
for(int i=1;i<=n;i++){
if(!vis[i]){
a[u]=i;
vis[i]=1;
dfs(u+1);
vis[i]=0;
}
}
}
int main(){
cin>>n;
dfs(1);
return 0;
}
P1157 组合的输出
题目描述
排列与组合是常用的数学方法,其中组合就是从 n 个元素中抽出 r 个元素(不分顺序且 r≤n),我们可以简单地将 n 个元素理解为自然数 1,2,...,n,从中任取 r 个数。
现要求你输出所有组合。
例如 n=5,r=3,所有组合为:
123,124,125,134,135,145,234,235,245,345。
输入格式
一行两个自然数 r(1<n<21,0≤r≤n)。
输出格式
所有的组合,每一个组合占一行且其中的元素按由小到大的顺序排列,每个元素占三个字符的位置,所有的组合也按字典顺序。
注意哦!输出时,每个数字需要 33 个场宽。
以 C++ 为例,你可以使用下列代码:
cout << setw(3) << x;
输出占 33 个场宽的数 x。注意你需要头文件 iomanip
。
输入输出样例
输入 #1
5 3
输出 #1
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
解题思路
这题其实就是搜索+回溯(可是我仍然写了半个多小时)
首先,第一组排列一定是 1∼k(前 k 个元素),于是进行一个预处理;
接下来开始搜:
先从第 k 个元素搜,搜完前 k−1 个元素为 1∼k−1 时最后一个元素的所有情况(边搜边记);
搜完了(前 k 个元素填满了或任意一个元素 >n 了或前 k 个元素未填满,但目前元素已经到 n 了(下一步就没了))就回溯(第一种情况下输出);
共搜 k 次,每次范围向前 1个元素,初始值为 x(目前在搜第几个元素)
搜完了就好了。
AC
cpp
#include<bits/stdc++.h>
using namespace std;
int r,a[100],n;
void dfs(int k){
int i;
if(k>r){
for(i=1;i<=r;i++){
cout<<setw(3)<<a[i];
}
cout<<endl;
return ;
}
for(i=a[k-1]+1;i<=n;i++){
a[k]=i;
dfs(k+1);
}
}
int main()
{
cin>>n>>r;
dfs(1);
return 0;
}
P1236 算24点
题目描述
几十年前全世界就流行一种数字游戏,至今仍有人乐此不疲.在中国我们把这种游戏称为"算 24点"。您作为游戏者将得到 4 个 1∼9 之间的自然数作为操作数,而您的任务是对这 4个操作数进行适当的算术运算,要求运算结果等于 24。
您可以使用的运算只有:+,-,*,/您还可以使用 ()来改变运算顺序。注意:所有的中间结果须是整数,所以一些除法运算是不允许的(例如,(2 ×2)/4 是合法的,2×(2/4)是不合法的)。下面我们给出一个游戏的具体例子:
若给出的 4 个操作数是:1 、 2 、 3 、 7,则一种可能的解答是 1+2+3 ×7=24。
输入格式
只有一行,四个1到9之间的自然数。
输出格式
如果有解的话,只要输出一个解。输出的是三行数据,分别表示运算的步骤。
-
其中第一行是输入的两个数和一个运算符和运算后的结果;
-
第二行是第一行的结果和一个输入的数据、运算符、运算后的结果,或者是另外两个数的输出结果;
-
第三行是前面的结果第二行的结果或者剩下的一个数字、运算符和 =24=24。如果两个操作数有大小的话则先输出大的。
如果没有解则输出 No answer!
。
如果有多重合法解,输出任意一种即可。
注:所有运算结果均为正整数。
输入输出样例
输入 #1
1 2 3 7
输出 #1
2+1=3
7*3=21
21+3=24
解题思路
我的思路是从剩下的数中不断枚举2个数,一一尝试加减乘除四则运算。题目要求从较大数开始输出,我就要求运算时前一个量大于等于(一定要加"等于"!否则60分!)后一个量。然后将结果存在较大量中,并设较小量为已访问。跳过已访问的数,不断从第一个数搜到第四个数搞运算,顺便将运算符号和运算的两个量存起来。当只剩最后一个未访问数时,若其为24,输出即可。
易错点:
1、当4个数中出现两个及以上相同数时,注意两数相同也可以进行运算,但必须保证运算的两个量下标不同。(get60分)
输入:2 2 2 4 输出:2+2=4 4+2=6 6*4=24
2、运算中必须保证只有整除(无余数)。
3、得出的24可以在4个数中的任意一个(要把四个数全搜一遍)
4、运算中不能出现0和负数(特判解决)。
5、可能会出现两个数反复运算(即最后结果被设为已访问),此时特判最后结果未访问即可(get70分)。
6、必须保证24是最后一步算出来的(在运算出结果时判断,若为24则return,get100分)。
输入:1 2 4 6 输出:2-1=1 4*1=4 6*1=24
AC
cpp
#include <bits/stdc++.h>
using namespace std;
int a[5];
char opt[5]= {' ','+','-','*','/'};
int F(int x,int k, int y)
{
if(k==1)
return x+y;
if(k==2)
return max(x,y)-min(x,y);
if(k==3)
return x*y;
return (y==0 || x<y || x%y!=0) ? -999999 : x/y;
}
void Out(int a,int b,int c,int d,int e,int f,int k1,int k2,int k3)
{
printf("%d%c%d=%d\n",max(a,b),opt[k1],min(a,b),F(max(a,b),k1,min(a,b)));
printf("%d%c%d=%d\n",max(c,d),opt[k2],min(c,d),F(max(c,d),k2,min(c,d)));
printf("%d%c%d=%d\n",max(e,f),opt[k3],min(e,f),F(max(e,f),k3,min(e,f)));
exit(0);
}
int main()
{
scanf("%d%d%d%d", &a[1],&a[2],&a[3],&a[4]);
sort(a+1,a+5);
do
{
for (int i = 1; i <= 4; i++)
for (int j = 1; j <= 4; j++)
for (int k = 1; k <= 4; k++)
if (F(F(F(a[1],i,a[2]),j,a[3]),k,a[4])==24) //((a?b)?c)?d
Out(a[1],a[2],F(a[1],i,a[2]),a[3],F(F(a[1],i,a[2]),j,a[3]),a[4],i,j,k);
else if (F(F(a[1],i,a[2]),k,F(a[3],j,a[4])) == 24)//(a?b)?(c?d)
Out(a[1],a[2],a[3],a[4],F(a[1],i,a[2]),F(a[3],j,a[4]),i,j,k);
}while (next_permutation(a + 1, a + 5));
puts("No answer!");
return 0;
}
结尾
希望大家多多关注!!!
如果你能支持一下我,我十分感谢!!!
如果有人想在洛谷上做题,可以点下方链接:
如果你喜欢或想了解一下其他的算法,可以看看以下这些:
洛谷指南
题目详解系列(部分):
【万题详解】P1314 [NOIP2011 提高组] 聪明的质监员-CSDN博客
游戏系列:
C++讲解系列(算法):
C++:第十二讲DFS深搜(二)_c++匿名函数dfs-CSDN博客
前缀和与差分:
贪心:
C++讲解系列(基础入门):
排序:
函数:
C++第6讲max和min函数_c++ min函数-CSDN博客
for循环&数组:
if语句&else语句及运算:
C++第三讲:C++中的逻辑运算符及if else语句-CSDN博客
基础:
欢迎收看,希望大家能三连!
最后认识一下,我是爱编程的喷火龙廖,我们有缘再见!