算法笔记 分治:循环赛日程 棋盘覆盖 选择问题 输油管问题 整数因子分解
一.循环赛日程
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cmath>
#define MAX 100
using namespace std;int a[MAX][MAX];// 拷贝方阵
// 从左上角顶点为(from_x, from_y)复制到左上角顶点为(to_x,to_y),行列式都为r
void Copy(int tox, int toy, int fromx, int fromy, int r)
{for (int i=0; i<r; i++)for (int j=0; j<r; j++) a[tox+i][toy+j] = a[fromx+i][fromy+j];
}// 人数是2^k
void Table(int k)
{ int i, r;int n = 1 << k; //构造正方形表格的第一行数据for (i=0; i<n; i++)a[0][i] = i + 1;// 分治,从第一行开始向下一行复制// 然后从已经产生的列表向下继续复制(原来又两行,就向下复制两行)for (r=1; r<n; r<<=1)for (i=0; i<n; i+=2*r){ Copy(r, r + i, 0, i, r); //①Copy(r, i, 0, r + i, r); //②}
}int main()
{Table(3);for(int i = 0;i < 8;i++){for(int j = 0;j < 8;j++)cout << a[i][j] << " ";cout<<endl;}
}
二.棋盘覆盖
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cmath>
#define MAX 1025
using namespace std;int board[MAX][MAX];
static int tile = 1; // 骨牌编号 // (tr,tc)是棋盘中左上角的方格坐标
//(dr,dc)是特殊方格坐标
// size是棋盘的行数或列数
void ChessBoard(int tr,int tc,int dr, int dc, int size)
{if(size == 1) return; // 递归出口,如果边长是1的话,那他就是特殊方格int t = tile++; // 骨牌编号 int s = size/2; // 划分小的棋盘 // 覆盖左上角子棋盘if(dr < tr + s && dc < tc + s) // 特殊方格在这个棋盘中ChessBoard(tr,tc,dr,dc,s); // 去划分更小的棋盘 else{// 没有特殊方格,用一个L骨牌中的一小格覆盖右下角,将这个小格当成特殊方格 // 到时候这些小格会拼成一个完整的L形骨牌board[tr+s-1][tc+s-1] = t;// 覆盖其他方格ChessBoard(tr,tc,tr+s-1,tc+s-1,s); } // 覆盖右上角子棋盘if(dr < tr + s && dc >= tc + s) // 特殊方格在这个棋盘中ChessBoard(tr,tc+s,dr,dc,s); // 去划分更小的棋盘 else{// 没有特殊方格,用一个L骨牌中的一小格覆盖左下角,将这个小格当成特殊方格 // 到时候这些小格会拼成一个完整的L形骨牌board[tr+s-1][tc+s] = t;// 覆盖其他方格ChessBoard(tr,tc+s,tr+s-1,tc+s,s); }// 覆盖左下角子棋盘if(dr >= tr + s && dc < tc + s) // 特殊方格在这个棋盘中ChessBoard(tr+s,tc,dr,dc,s); // 去划分更小的棋盘 else{// 没有特殊方格,用一个L骨牌中的一小格覆盖右上角,将这个小格当成特殊方格 // 到时候这些小格会拼成一个完整的L形骨牌board[tr+s][tc+s-1] = t;// 覆盖其他方格ChessBoard(tr+s,tc,tr+s,tc+s-1,s); } // 覆盖右下角子棋盘if(dr >= tr + s && dc >= tc + s) // 特殊方格在这个棋盘中ChessBoard(tr+s,tc+s,dr,dc,s); // 去划分更小的棋盘 else{// 没有特殊方格,用一个L骨牌中的一小格覆盖左上角,将这个小格当成特殊方格 // 到时候这些小格会拼成一个完整的L形骨牌board[tr+s][tc+s] = t;// 覆盖其他方格ChessBoard(tr+s,tc+s,tr+s,tc+s,s); }
}int main()
{int k;int dr, dc;cout << "输入边长k,即size = 2^k" << endl; cin >> k;int size = pow(2, k);cout << "特殊方格坐标" << endl; cin >> dr >> dc; ChessBoard(0,0,dr,dc,size);for(int i = 0;i < size;i++){for(int j = 0;j <size;j++)cout << board[i][j] << " ";cout << endl;}
}
三.选择问题
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cmath>
#define NUM 1001
using namespace std;int a[NUM];// 选择第k小的元素
int select(int *a, int left, int right, int k)
{// 找到第k小的元素if(left >= right) return a[left];int i = left;int j = right + 1;// 将左边的元素化为分界点int pivot = a[left];// 把左侧>=pivot的元素和右侧<=pivot的原色交换while(true){// 在左侧寻找>=pivot的元素do {i += 1; } while(a[i] < pivot);// 在右侧寻找<=pivot的元素 do {j -= 1;} while(a[j] > pivot);//cout << i << " " << j << endl;if(i >= j) break;swap(a[i], a[j]);} // 快排中 num_left = j - leftif(j - left + 1 == k) return pivot;a[left] = a[j]; // 交换pivot和a[j],走到这一步,p后面的数据已经排好序了// i和j找的是离p最近的大的数字和小的数字 a[j] = pivot;//cout << "a[left]" << " " << a[left] << endl;//cout << "a[j]" << " " << a[j] << endl;//cout << "pivot" << " " << pivot << endl;//cout << endl;if(j - left + 1 < k)return select(a, j + 1,right, k - j + left - 1); // 往右边找elsereturn select(a, left, j - 1, k); // 往左边找 } int main()
{int n , k;cout << "输入数组个数和查找的元素大小的次数" << endl;cin >> n >> k;cout << "输入元素" << endl; for(int i = 0;i < n;i++){cin >> a[i];} cout << select(a, 0, n-1, k); }
四.输油管问题
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cmath>
#define NUM 1001
using namespace std;int a[NUM];// 选择第k小的元素
int select(int left, int right, int k)
{// 找到第k小的元素if(left >= right) return a[left];int i = left;int j = right + 1;// 将左边的元素化为分界点int pivot = a[left];// 把左侧>=pivot的元素和右侧<=pivot的原色交换while(true){// 在左侧寻找>=pivot的元素do {i += 1; } while(a[i] < pivot);// 在右侧寻找<=pivot的元素 do {j -= 1;} while(a[j] > pivot);//cout << i << " " << j << endl;if(i >= j) break;swap(a[i], a[j]);} // 快排中 num_left = j - leftif(j - left + 1 == k) return pivot;a[left] = a[j]; // 交换pivot和a[j],走到这一步,p后面的数据已经排好序了// i和j找的是离p最近的大的数字和小的数字 a[j] = pivot;//cout << "a[left]" << " " << a[left] << endl;//cout << "a[j]" << " " << a[j] << endl;//cout << "pivot" << " " << pivot << endl;//cout << endl;if(j - left + 1 < k)return select(j + 1,right, k - j + left - 1); // 往右边找elsereturn select(left, j - 1, k); // 往左边找 } int main()
{int n; // 油井数量 int x; // x坐标,无用 // a[]是y坐标cin >> n;for(int k = 0;k < n;k++){cin >> x >>a[k];} // 快排找中位数 int y = select(0, n-1, n/2);int min = 0;for(int i = 0;i < n;i++){min += (int)fabs(a[i] - y);} cout << min << endl;
}
五.整数因子分解
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cmath>
#define NUM 1001
using namespace std;int total;
void solve(int n){if(n == 1) total++; // 获得一个分解else for(int i = 2;i <= n;i++)if(n % i == 0) solve(n/i); // i是n的一个因数
}int main()
{int n;cin >> n;solve(n);cout << total;
}
算法笔记 分治:循环赛日程 棋盘覆盖 选择问题 输油管问题 整数因子分解相关推荐
- 算法篇-2-分治思想-棋盘覆盖归并排序Strasssen矩阵乘法循环赛安排
本系列所有代码https://github.com/YIWANFENG/Algorithm-github 分治思想 分治法基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些问题互相独立且与 ...
- 算法笔记_031:计算中值和选择问题(Java)
目录 1 问题描述 2 解决方案 2.1 计算中值问题 2.2 选择问题 1 问题描述 中值问题是求一个n个数列表中某一数组下标k,它要求该下标元素比列表中的一半元素大,又比另一半元素小,这个中 ...
- 棋盘覆盖问题——详解(C++)
[问题描述] 在一个 2 ^k × 2 ^k 个方格组成的棋盘中,若有一个方格与其他方格不同,则称该方格为一特殊方格,且称该棋盘为一个特殊棋盘.显然特殊方格在棋盘上出现的位置有4^k 种情形.因而对任 ...
- java棋盘问题_0x03大数问题(JAVA解决棋盘覆盖,A+B Problem II)
常见的有棋盘覆盖和A+B问题,这类问题牵扯到的数值都比较大,如果用一般的数值类型,肯定输出不了,所以就要想一个办法,怎么把大数转换一下输出. A+B Problem II 时间限制:3000 ms | ...
- 计算机基础算法棋盘覆盖,分治算法求解棋盘覆盖问题互动教学过程.doc
分治算法求解棋盘覆盖问题互动教学过程 分治算法求解棋盘覆盖问题互动教学过程 摘要:针对算法设计与分析课程难度较大.对学生编程能力要求较高的现状,通过对棋盘覆盖问题的分治算法求解过程进行互动教学设计,引 ...
- 算法系列(一):分治策略--棋盘覆盖
算法系列(一):分治策略--棋盘覆盖 一.分析 问题描述: 图1-1 k=2时的一个特殊棋盘 在一个 2^k * 2^k 个方格组成的棋盘中,若恰有一个方格与其它方格不同,则称该方格为一特殊方格,且 ...
- 棋盘覆盖问题 java_Java基于分治算法实现的棋盘覆盖问题示例
本文实例讲述了Java基于分治算法实现的棋盘覆盖问题.分享给大家供大家参考,具体如下: 在一个2^k * 2^k个方格组成的棋盘中,有一个方格与其它的不同,若使用以下四种L型骨牌覆盖除这个特殊方格的其 ...
- 算法设计与分析——递归与分治策略——棋盘覆盖
问题描述 棋盘覆盖问题要求在2^k * 2^k 个方格组成的棋盘中,你给定任意一个特殊点,用一种方案实现对除该特殊点的棋盘实现全覆盖. 建立模型如图: 解决方案就是利用分治法,将方形棋盘分成4部分,如 ...
- 分治算法--棋盘覆盖
问题描述 在一个2^k×2^k 个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘.在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特 ...
最新文章
- Openfire XMPP Smack RTC IM 即时通讯 聊天 MD
- c2064 项不会计算为接受0个参数的函数_无网格法理论与Matlab程序设计(6)——传统径向基点插值(RPIM)形函数...
- 调试九法:软硬件错误的排查之道书评
- sle linux lftp禁止匿名登陆_软件测试常用linux命令整理
- 点击事件为什么会失效_Spring事务原理?事务在方法间如何传播?为什么会失效?...
- LeetCode 134. 加油站(贪心)
- 随想录(中断中真的不能上下文切换吗)
- c语言自定义double函数例子,C语言的那些事——sqrt()函数 跟 double型数据的“%lf”...
- 查看docker内部路径_web应用在Docker容器中部署(Windows)
- 批量修改Project视图中Prefab的名字
- CMU和谷歌联手放出XL号Transformer!提速1800倍 | 代码+预训练模型+超参数
- 解决<c:if>无else的问题
- 广联达登录显示服务器异常去回答,广联达设置服务器异常5
- html+xml+js语言切换插件,你在Eclipse中使用什么CSS / JS / HTML / XML插件?
- 转:什么是Node.js?
- Django2.0异常:'Specifying a namespace in include() without providing an app_name '
- 移动前端开发和web前端开发的区别
- 项目发布到Tomcat后,网页图片不显示
- redis-trib.rb和redis-cli部署redis主从集群的异同
- 2021SC@SDUSC Zxing开源代码(十一)Data Matrix二维码(四)