这道题手动模拟一下就好了,是一道入门题,代码非常清楚不多说
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
int n, m;
cin >> n >> m;
long long sum = 0;
long long sum1 = 0;
for (int i = 1; i <= m; i++) //枚举列
{
for (int j = 1; j <= n; j++) //枚举行
{
if (i == j) //行等于列代表是正方形
{
sum += (m - i + 1) * (n - j + 1);
}
else //否则是长方形
sum1 += (m - i + 1) * (n - j + 1);
}
}
cout << sum << " " << sum1;
return 0;
}
题目很清楚,有要给出所有满足条件的方案。实际上,这题转换一下:给定一个数字。将这个数字分成10份,看有几种分法。
第一个想法也是最快的思路应该就是10个for循环,
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
int n;
cin >> n;
if (n > 30) //每种配料只给1-3克,所以最大美味程度到30,n大于30就输出0就好了。
{
cout << "0";
return 0;
}
int way = 0;
for(int a=1;a<=3;a++)
for(int b=1;b<=3;b++)
for(int c=1;c<=3;c++)
for(int d=1;d<=3;d++)
for (int e = 1; e <= 3; e++)
for (int f = 1; f <= 3; f++)
for (int g = 1; g <= 3; g++)
for (int h = 1; h <= 3; h++)
for (int i = 1; i <= 3; i++)
for (int j = 1; j <= 3; j++)
if (a + b + c + d + e + f + g + h + i + j == n)
{
way += 1;
//cout << a << b << c << d << e << f << g << h << i << j << endl;
}
cout << way << endl;
for (int a = 1; a <= 3; a++)
for (int b = 1; b <= 3; b++)
for (int c = 1; c <= 3; c++)
for (int d = 1; d <= 3; d++)
for (int e = 1; e <= 3; e++)
for (int f = 1; f <= 3; f++)
for (int g = 1; g <= 3; g++)
for (int h = 1; h <= 3; h++)
for (int i = 1; i <= 3; i++)
for (int j = 1; j <= 3; j++)
if (a + b + c + d + e + f + g + h + i + j == n)
{
cout << a << " "<<b <<" "<< c <<" "<< d<<" " << e <<" " << f <<" " << g <<" " << h <<" " << i <<" " << j << endl;
}
return 0;
}
第二个思想就是递归思想。因为对于每一种配料实际上都是在做一样的事(我的测试有一个总是错,所以找了个比较好理解的贴上来,感谢洛谷的朋友)情❤️😒
😒:😒
#include<iostream>
using namespace std;
int s,t,n;
int a[11];
int b[10000][11];//一个二维数组,先出方案总数很难做呀
int c=1;
int num;
void ss(int k);
void pp(); //存方案
int main()
{
cin>>n;
ss(1);
cout<<num<<endl;
for(int i=1; i<c; i++) //输出所有方案
{
for(int j=1; j<=10; j++)
{
cout<<b[i][j]<<" ";
}
cout<<endl;
}
}
void ss(int k) //核心代码
{
for(int i=1; i<=3; i++)//每个只能加1,或2或3
{
s+=i; //s为总质量
a[k]=i; //k代表第几种食材,i代表当前食材用到的质量
if(k==10) //当用满10种食材,来判断是否满足条件,满足就存入方案
{
if(s==n)
pp();
}
else
ss(k+1);
s-=i;//s是全局变量,要手动恢复状态
}
}
void pp()
{
num++;
for(int i=1; i<=10; i++)
b[c][i]=a[i];//存数组
c++;
}
这道题思路很简单:
首先想象有3个桶子,然后把9个数放进这3个桶子,然后去判断这3个数是否满足三个数的比例是a🅱️c.所以一个递归就可以了。每次放满9个数,就去判断是否满足比例条件,满足就输出。否则回溯然后继续递归,回溯记得恢复环境。
#include<cstdio>
#include<iostream>
using namespace std;
int a, b, c;
int judge = 0;
int used[10]; //设置一个数组表明该数字有没有用过。
int serve[10]; //设置一个数组保存3个3位数
void dfs(int k) //k代表已经存放了几位数了,当存了9位数的时候就要判断是否符合答案了
{
if (k ==10)
{
//这个时候,serve数组已经保存了3个3位数。那么就要来判断了。
int x = 0;
int y = 0;
int z = 0;
for (int i = 1; i <= 3; i++)
{
x = x * 10;
x += serve[i];
}
for (int i = 4; i <= 6; i++)
{
y = y * 10;
y += serve[i];
}
for (int i = 7; i <= 9; i++)
{
z = z * 10;
z += serve[i];
}
if (x * b == y*a && x * c == a*z)
{
judge = 1;
cout << x << " " << y << " " << z << " " << endl;
}
return;
}
for (int i = 1; i <= 9; i++) //核心代码
{
if (used[i] != 1) //数字i没有被使用
{
used[i] = 1; //标记为已经使用
serve[k] = i; //存放路径
dfs(k + 1); //继续递归
used[i] = 0; //回溯的时候恢复环境
}
}
}
int main()
{
cin >> a >> b >> c;
dfs(1);
if (judge == 0)
cout << "No!!!";
return 0;
}
这道题也是用深搜。
1.数组a存放所有的数字
2.数组path存放选中的数字
3.这道题和上面非常像,其实不然,上面的dfs是全排列深搜,这里的dfs是类似迷宫路径的深搜,有什么区别呢?下面会给一个链接说明其中的区别(可能是明天添加进来,等下跑步减肥去了)😋
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int a[1000];
int serve[1000]; //辅助数组,记录当前数字是否被使用过
int path[1000]; //记录取得数字的组合(路径)
int n, m;
int ans = 0;
int judge_sushu(int target) //判断是不是素数
{
if (target == 2) //是素数
return 0;
for (int i = 2; i <sqrt(target); i++)
{
if (target % i == 0) //不是素数
return 1;
}
return 0; //是素数
}
void dfs(int k,int pre)
{
if (k == m) //取到m个数
{
int sum = 0;
for (int i = 0; i < k; i++)
{
sum += path[i];
}
if (judge_sushu(sum)==0)
{
ans += 1;
}
return;
}
for (int i = pre; i < n; i++) //pre是什么呢?因为取数是一直往后取,要不重复遍历,所以下一次取数是在前一次取数的后面开始遍历
{
path[k] = a[i];
dfs(k + 1,i); //遍历当前取数的后面的数
}
}
int main()
{
cin >> n>>m; //n个数里面拿3个数相加的和是素数
for (int i = 0; i < n; i++)
cin >> a[i];
dfs(0,0);
cout << ans;
return 0;
}
发现这几题都是一样的套路。这还是深搜。和之前的做法一模一样
但是这里注意一下,这里要求格式是右对齐三位宽度.所以用%3d.
不会用格式的小伙伴可以参考这里printf的输出格式说明
#include<iostream>
#include<cstring>
using namespace std;
int n, r; //n个数取r个数组成的全排列
int path[100000];
void dfs(int k,int pre)//这是迷宫路径,不是全排列
{
if (k == r+1)
{
for (int i = 1; i <= r; i++)
printf("%3d", path[i]);
cout << endl;
return;
}
for (int i = pre; i <= n; i++)
{
path[k] = i;
dfs(k + 1, i+1);
}
}
int main()
{
cin >> n >> r;
dfs(1,1);
return 0;
}
今天晚上的5个题就结束了,继续加油!