暑期集训第四周与题目精讲(7.31-8.6)

Point1  贪心算法

Point2  关于>>的代码

Point3  二叉树

“中序遍历+先序遍历”,能确定一棵树。

“中序遍历+后序遍历”,能确定一棵树。

“先序遍历+后序遍历”,能确定一棵树。

Point4  二叉堆

Point5  全排列

Point6  广度优先搜索基本模板

NO.1

题目描述:

 

题意分析:三国中的n个武将之间两两之间都有一个默契值。你和机器人需要进行轮流选角,最后选完以后,派出所选的队伍里默契值最大的两个武将出战,比较双方的默契值哪个更大。

解题思路:你每次选一个,计算机会把你选的那个角色对应的最佳搭档给选了。也就是说你无法获得这个角色的最佳搭档,但其实,计算机也无法获得他选的角色的最佳搭档。所以这一个组合相当于废了然后你接下来选的角色,只需要是上一个角色的次佳搭档即可。我们假设,计算机接下来会把你选的次佳搭档中剩余的最佳搭档给选了,但其实这个角色(真正的最佳搭档)已经被你第一次给选了。所以无论如何你都是必赢的那么接下来只需要找每一个角色的次佳搭档是多少,然后找最大的那一对即可

复杂度分析:O(n)

带注释的代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std; 
int a[505][505];//用二维数组来储存
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        for(int j=i+1;j<=n;j++){
            scanf("%d",&a[i][j]);
            a[j][i]=a[i][j];//小涵和计算机选的武将是对称的
        }
    }
    int ans=0;//初始化答案
    for(int i=1;i<=n;i++){
        sort(a[i]+1,a[i]+1+n);//将默契值从小到大排序
        if(a[i][n-1]>ans){
        	ans=a[i][n-1];//选出次佳搭档中最大的那个
		}
    }
    printf("1\n%d\n",ans);//一定有解,即小涵一定会赢
    return 0;
}

NO.2

题目描述:

题意分析:

解题思路:

复杂度分析:

带注释的代码:

NO.3

题目描述:在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N = 2e6 + 10;
const int mod = 100003;
map<string, int> mp;

int a[N];
int n, m;
int ans;
int check(int x){
    for(int i = 2; i * i <= x; i++){
        if(x % i == 0){
            return 0;
        }
    }
    return 1;
}
void dfs(int k, int p, int sum){
    //k表示选了几个数
    //p表示从第几个数开始选,为了防止重复选择
    //sum表示选的数字的和
    if(k == m){
        ans += check(sum);
        return ;
    }
    if(k + n - p + 1 < m){
        //剩下的数字不够选,直接return
        return ;
    }
    for(int i = p; i <= n; i++){
        dfs(k + 1, i + 1, sum + a[i]);
    }
}
int main(){
    
    cin >> n >> m;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
    }
    dfs(0, 1, 0);
    cout << ans << '\n';
    return 0;
}

NO.4

题目描述:

题意分析:有一个 n*m 的棋盘,在某个点 (x, y)上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。输入格式 输入只有一行四个整数,分别为 n, m, x, y。输出格式 一个 n *m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 -1。

解题思路:数据规模与约定对于全部的测试点,保证 1 <=x <=n<=400,1<= y <=m <=400。思路: 广搜,但是要注意的是国际象棋中马的走法:每步棋先横走或直走一格,然后再往外斜走一格。所以有8种方向可以走:3 3 1 10 3 2 3 -1 1 2 1 4,然后在每个节点都记录一下当前已经走了几步,最后挨个输出就行,由于标记了是否走过,避免了重复走的情况,所以step记录的值都是最少的步骤,就达到了记录最小步数的目的。

带注释的代码:

#include<bits/stdc++.h>
using namespace std;
int n,m;
int dir[][2]={{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2}};
struct pos{
	int r,c,d;
	pos(int a=0,int b=0,int d=0):r(a),c(b),d(d){} 
};
int mp[405][405];
void bfs(int r,int c);
int main(){
	int sr,sc;
	cin>>n>>m>>sr>>sc;
	memset(mp,-1,sizeof mp);
	bfs(sr,sc);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cout<<mp[i][j]<<'\t';
		}
		cout<<endl;
	}
	return 0;
}
void bfs(int r,int c){
	queue<pos>q;
	q.push(pos(r,c));
	mp[r][c]=0;
	while(!q.empty()){
		pos p=q.front();
		q.pop();
		for(int i=0;i<8;i++){
		    int nr=p.r+dir[i][0];
		    int nc=p.c+dir[i][1];
		    int nd=p.d+1;
	    	if(nr>=1&&nr<=n&&nc>=1&&nc<=m&&mp[nr][nc]==-1){
			    mp[nr][nc]=nd;
			    q.push(pos(nr,nc,nd));
		    }
	    }
	}
} 

NO.5

题目描述:

题意分析:在 3×33×3 的棋盘上,摆有八个棋子,每个棋子上标有 11 至 88 的某一数字。棋盘中留有一个空格,空格用 00 来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为 123804765123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。

带注释的代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read() {
	ll f = 1, x = 0; char ch;
	do {ch = getchar(); if (ch == '-')f = -1;} while (ch > '9' || ch < '0');
	do {x = x * 10 + ch - '0'; ch = getchar();} while (ch >= '0' && ch <= '9');
	return f * x;
}
char s[15];
char goal[] = {'1', '2', '3', '8', '0', '4', '7', '6', '5'};
int maxdepth;
inline int h(char *cur) {
	int res = 0;
	for (int i = 0; i < 9; i ++ ) {
		if (goal[i] != cur[i] && cur[i] != 0) res++;
	}
	return res;
}
int dx[] = {0, 1, -1, 0};
int dy[] = {1, 0, 0, -1};
bool dfs (int depth, char *a, int pre) {
	if (h(a) == 0) return true;
	if (depth + h(a) - 1 > maxdepth) return false;
	int sx, sy;
	for (int i = 0; i < 9; i ++ )
		if (a[i] == '0') sx = i / 3 + 1, sy = i % 3 + 1;
	for (int i = 0; i < 4; i ++ ) {
		int xx = dx[i] + sx, yy = dy[i] + sy;
		if (xx < 1 || xx > 3 || yy < 1 || yy > 3 || (pre + i == 3)) continue;
		swap(a[(xx - 1) * 3 + yy - 1], a[(sx - 1) * 3 + sy - 1]);
		if (dfs(depth + 1, a, i)) return true;
		swap(a[(xx - 1) * 3 + yy - 1], a[(sx - 1) * 3 + sy - 1]);
	}
	return false;
}
int main() {
	scanf ("%s", s);
	if (h(s) == 0) {puts("0"); return 0;}
	for (maxdepth = 1; ; maxdepth ++ ) {
		if (dfs(0, s, -1)) {
			printf ("%d\n", maxdepth);
			return 0;
		}
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是求解多元多项式回归的 MATLAB 代码: ```matlab % 输入数据 x1 = [36.4 37.2 37.2 36.2 31.5 28.9 27.2 26.7 26.1 26.1 25.4 25.3 25.4]'; x2 = [50.0 52.0 49.0 51.0 68.0 74.0 83.0 82.0 88.0 88.0 90.0 88.0 87.0]'; x3 = [982.9 982.2 981.8 981.6 982.3 982.6 983.4 983.5 984.0 983.6 984.4 984.5 984.4]'; y = [-7.30 -7.36 -7.35 -7.33 -7.31 -7.30 -7.26 -7.22 -7.21 -7.23 -7.18 -7.17 -7.14]'; % 构建设计矩阵X X = [ones(size(x1)) x1 x2 x3 x1.^2 x1.*x2 x1.*x3 x2.^2 x2.*x3 x3.^2]; % 求解回归系数 beta = X \ y; % 构建预测模型 model = @(x1,x2,x3) beta(1) + beta(2)*x1 + beta(3)*x2 + beta(4)*x3 ... + beta(5)*x1.^2 + beta(6)*x1.*x2 + beta(7)*x1.*x3 ... + beta(8)*x2.^2 + beta(9)*x2.*x3 + beta(10)*x3.^2; % 预测并绘制拟合图 x1fit = min(x1):0.1:max(x1); x2fit = min(x2):0.1:max(x2); x3fit = min(x3):0.1:max(x3); [X1FIT,X2FIT,X3FIT] = meshgrid(x1fit,x2fit,x3fit); YFIT = model(X1FIT,X2FIT,X3FIT); figure; plot3(x1,x2,x3,'o',x1fit,x2fit,x3fit,'*'); hold on; mesh(X1FIT,X2FIT,X3FIT,YFIT); xlabel('x1'); ylabel('x2'); zlabel('x3'); title('拟合图'); % 绘制残差图 YFIT = model(x1,x2,x3); figure; plot(YFIT - y,'o'); xlabel('样本编号'); ylabel('残差'); title('残差图'); ``` 运行上述代码后,会先绘制拟合图,然后绘制残差图。拟合图中,蓝色的点表示原始数据,红色的点表示拟合值,可以看到拟合值与原始数据比较接近;残差图中,横轴表示样本编号,纵轴表示残差,残差的分布应该比较均匀,没有明显的规律。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值