7.2:JavaScript学习
7.3:HTML+css+JavaScript简单实践练习
7.4:完成登陆注册界面
太丑了,后期会继续修改
7.5:刷题
A - 数的计算
题目大意:
给出正整数 n,要求按如下方式构造数列
- 只有一个数字 n 的数列是一个合法的数列。
- 在一个合法的数列的末尾加入一个正整数,但是这个正整数不能超过该数列最后一项的一半,可以得到一个新的合法数列。
问你可以表示几种合法数列
思路:
从长度为1开始,逐步计算合法数列的个数,直到计算出长度为n的合法数列的个数。这样可以去重
首先我们根据给出的样例:
6
6,1
6,2
6,3
6,2,1
6,3,1
一共有6种合法数列
1.首先,将当前长度为i的数列视为一个合法数
2.因为在构成一个新的合法序列时,一个合法的数列的末尾加入一个正整数,但是这个正整数不能超过该数列最后一项的一半。所以我们就可以用两个循环来实现达到这种效果。
3.外层循环从1开始遍历到n,每次进入循环都要a[i]++因为一个数可以构成合法序列
4.内层循环从1到i/2,累加到a[i]中 表示要将一个数添加到当前数列的末尾。
代码
#include <iostream>
using namespace std;
int main() {
int a[1005] = { 0 };
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
a[i]++;
for (int j = 1; j <= i / 2; j++) {
a[i] += a[j];
}
}
cout << a[n] << endl;
return 0;
}
B - 小A点菜
题意:
有一个人他有m元,然后在拥有n种菜系的餐馆去吃饭,问你在把m元用完的情况下一共有多少种点菜的方法
最开始一看到这个我就想到dfs,写完一提交TLE,
#include<bits/stdc++.h>
using namespace std;
const int N=1e2+10;
int a[N],book[N];
int n,m,sum=0;
void dfs(int money,int x){
if(money==m){
sum++;
return ;
}
if(money>m){
return;
}
for(int i=x;i<=n;i++){
if(book[i]==0){
money+=a[i];
book[i]=1;
dfs(money,i+1);
money-=a[i];
book[i]=0;
}
}
return ;
}
int main(){
cin >> n >> m;
for(int i=1;i<=n;i++){
cin >> a[i];
}
dfs(0,1);
cout << sum ;
}
然后重新想了想,发现这是一个很经典的背包问题(拿与不拿)取最优
#include<iostream>
using namespace std;
const int N = 1e3 + 10;
int a[N];
long long dp[N][N];
int main() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
dp[0][0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= m; j++) {
dp[i][j] = dp[i - 1][j];
if (j >= a[i]) {
dp[i][j] += dp[i - 1][j - a[i]];
}
}
}
cout << dp[n][m] << endl;
return 0;
}
C - 南蛮图腾
题意:
就是让你输出图腾的样式
首先我们可以观察规律,图腾是怎么变化的。当n为1的时候是这样
n为2时,是由n=1时的图形变化而来,分别向上和向下复制得到
n为3时,是由n=2时的图形变化而来,分别向上和向下复制得到
由此我们可以发现规律
以及在每一次复制的时候每个三角形的偏移量
每一次复制得到的图形都是由前一个平移得到,所以我们就可以用递归的思想去完成这个题目,当n==1的时候输出小三角形的形状
现在还有一个问题,如何正确的输出小三角形的形状,因为形状是由空格和/ \ _构成,所以我们可以将这个三角形放在一个矩形里面,把矩形初始化为空格,最后输出矩形
下面是三角形各边的坐标
最开始我用的是静态数组,一直有错误。
最后改为动态分配空间就通过了
#include <iostream>
#include <cmath>
using namespace std;
void solve(char** map, int x, int y, int n) {
// 基础三角形
if (n == 1) {
map[x][y + 1] = '/';
map[x + 1][y] = '/';
map[x][y + 2] = '\\';
map[x + 1][y + 3] = '\\';
map[x + 1][y + 1] = '_';
map[x + 1][y + 2] = '_';
return;
}
int dis = pow(2, n); // 计算偏移量
solve(map, x, y + dis / 2, n - 1);
solve(map, x + dis / 2, y, n - 1);
solve(map, x + dis / 2, y + dis, n - 1);
}
int main() {
int n;
cin >> n;
int size = pow(2, n + 1); // 计算数组大小
char** map = new char* [size];
for (int i = 0; i < size; i++) {
map[i] = new char[size];
for (int j = 0; j < size; j++) {
map[i][j] = ' ';
}
}
solve(map, 0, 0, n);
int dis = pow(2, n); // 计算偏移量
for (int i = 0; i < dis; i++) {
for (int j = 0; j < dis * 2; j++) {
cout << map[i][j];
}
cout << endl;
}
return 0;
}
D - 幂次方
题意:就是让你将你输入的n用2的幂次方表示出来(得是最简,即只有2的0次,一次和二次)
如
1315=2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)
思路:
一看这种题目就想到了递归
我们知道任何正整数都可以表示为若干个 2 的幂次方的和,例如 n = 2^a + 2^b + ... + 2^z。我们可以通过递归解决这个问题:
1.首先定出口:如果 n 等于 0,返回 "0"。如果 n 等于 1,返回 "2(0)"。如果 n 等于 2,返回 "2"。如果 n 等于 3,返回 "2+2(0)"。
2.递归步骤:如果 n 大于 3,我们找到小于或等于 n 的最大的 2 的幂次数 m。也就是说,我们需要找到最大的 m,使得 2^m<=n.我们可以通过log2(n)来找到这个m
3.检查 n 是否为 2 的幂次方:我们检查 n 是否等于 2^m。如果是,我们递归地解决 m,然后返回 "2(" + solve(m) + ")"。如果不是,我们递归地解决 m 和 n-2^m,然后返回 "2(" + solve(m) + ")+" + solve(n-2^m)。
#include<iostream>
#include <cmath>
using namespace std;
string solve(int n) {
if (n == 0) {
return "0";
}
else if (n == 1) {
return "2(0)";
}
else if (n == 2) {
return "2";
}
else if (n == 3) {
return "2+2(0)";
}
else {
int m = log2(n);
if ((1 << m) == n) {
// n 是 2 的幂次
return "2(" + solve(m) + ")";
}
else {
// n 不是 2 的幂次
return "2(" + solve(m) + ")+" + solve(n - (1 << m));
}
}
}
int main() {
int n;
cin >> n;
cout << solve(n);
return 0;
}