F. 方格填数 #深搜

题意

有\(10\)个格子,填入0~9的数字。要求:连续的两个数字不能相邻。(左右、上下、对角都算相邻),求可能的填数方案数。

   +--+--+--+
| | | |
+--+--+--+--+
| | | | |
+--+--+--+--+
| | | |
+--+--+--+

分析

题目有点表述不清,实际上要我们在所有格子中只填一种数字。题目中的“相邻”,是指元素在位置上的相邻。而“连续”,是指数字意义上的连续,比如4 5 7,中间的5,它与右边的7不是连续的,但它与左边的4连续,即\(5 - 4 = 1\)。因此,在判断是否连续的时候,需要判断特定点的左、左上、上、右上的数字,与特定点的绝对值之差是否为\(1\),若为\(1\)则说明相邻数字是连续的,不合题意。

由于数据规模不大,我们从第一行第二列开始搜,第三行第三列作为终点。

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <cstring>
#include <vector>
#include <cmath>
#include <unordered_map>
#include <set>
#include <cmath>
using namespace std;
using ll = long long;
const int MAXN = 105;
int Ma[5][5], ans = 0, used[11];
int dx[] = {0, -1, -1, -1};
int dy[] = {-1, -1, 0, 1}; //左、左上、上、右上
bool Judge(int x, int y, int num){ //四个方向判断该点是否满足题意要求
for(int t = 0; t < 4; t++){
int nx = x + dx[t], ny = y + dy[t];
if(1 <= nx && nx <= 3 && 1 <= ny && ny <= 4 && abs(Ma[nx][ny] - num) == 1)
return false;
}
return true;
}
void DFS(int x, int y){
if(x >= 3 && y >= 4){
ans++;
return;
}
for(int i = 0; i < 10; i++){ //枚举数字
if(used[i]) continue; //之前路径已经使用过该数字
if(Judge(x, y, i)){
Ma[x][y] = i;
used[i] = true;
if(y + 1 <= 4) DFS(x, y + 1);
else DFS(x+1, 1); //列数已达到边界,到下一行的第一列
used[i] = false;
}
}
}
int main(){
for(int i = 0; i <= 4; i++)
for(int j = 0; j <= 4; j++) Ma[i][j] = -2; //填个不会与0-9相差一的数字。
DFS(1, 2); //从第一行第二列开始搜
cout << ans << endl;
//cout << 1580 << endl;
return 0;
}

G. 剪邮票 #枚举 #连通性

题意

有\(12\)张连在一起的\(12\)生肖的邮票。现在你要从中剪下\(5\)张来,要求必须是连着的。(仅仅连接一个角不算相连)现要你计算共有多少种不同的剪取方法。

分析

要注意到邮票当中每个格子的数字是不相同的!只要选定的路径不同,就代表了不同的剪取方法了。

不妨定义个状态表,如a[12] = {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};,代表一开始的时候,第\(0\)到\(6\)个格子"不使用",第\(7\)到\(11\)个格子会"使用"。接下来就用全排列函数去枚举这个状态表。

在当前的状态表下,我们就要判断在实际位置中"使用"的格子,是否是连通的!如何判断连通?从某一个“使用”的格子出发,深搜去寻找每一个有标记“使用”的格子。如果“使用”的格子是相互连通的,按理说,只需要深搜一次,否则,就是不连通的。

#include <string>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <stack>
#include <cmath>
#include <queue>
#include <map>
#include <vector>
#include <deque>
#include <algorithm>
#include <unordered_map>
using namespace std;
using ll = long long;
const int MAXN = 1e5 + 5;
int ans = 0, used[5][5];
int a[12] = {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};
int dx[] = {1, 0, -1, 0};
int dy[] = {0, -1, 0, 1};
void DFS(int x, int y){
for(int t = 0; t < 4; t++){
int nx = x + dx[t], ny = y + dy[t];
if(1 <= nx && nx <= 3 && 1 <= ny && ny <= 4 && used[nx][ny]){
used[nx][ny] = 0; //消除标记
DFS(nx, ny);
}
}
}
int main(){
do{
memset(used, 0, sizeof(used));
int k = 0, cnt = 0;
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 4; j++)
used[i][j] = a[k++];
for(int i = 1; i <= 3; i++){
for(int j = 1; j <= 4; j++){
if(used[i][j]){ //找到特定点
cnt++;
DFS(i, j); //从该特定点出发,去将所有与之连通的点进行访问,并消除它们的标记
}
}
}
if(cnt == 1) ans++; //说明只有一个连通块
}while(next_permutation(a, a + 12)); //枚举这12个数的全排列
printf("%d\n", ans);
}

H. 四平方和 #暴力 #哈希表

题意

每个正整数都可以表示为至多\(4\)个正整数的平方和。如果把0包括进去,就正好可以表示为\(4\)个数的平方和。如:

\(5 = 0^2 + 0^2 + 1^2 + 2^2\)

\(7 = 1^2 + 1^2 + 1^2 + 2^2\)

对于一个给定的正整数\(N\)(\(\leq 5000000\)),可能存在多种平方和的表示法。要求你对4个数排序:\(0 \leq a \leq b \leq c \leq d\)

并对所有的可能表示法按 \(a,b,c,d\) 为联合主键升序排列,最后输出第一个表示法。

分析

该题在NOJ中三重循环可以过,这里给一下\(O(\sqrt{N}\times\sqrt{N})\)的代码。(感谢为神)

我们一开始容易想到枚举\(a,b,c\),然后通过\(\sqrt{N-a^2-b^2-c^2}\)确定\(d\)。我们能不能将枚举\(c\)的那层循环优化掉?我们可以个哈希表去存下每个\(c^2+d^2\)所对应的\(c\),也就说,定义哈希表mymap[](普通数组模拟下即可),则mymap[c*c+d*d]=c,首先要预处理,为所有\(c^2+d^2\)结果记录其所对应的\(c\),接下来我们只需要枚举\(a,b\),计算\(cur=\sqrt{N-a^2-b^2}\),然后用哈希表读出\(cur\)所对应的\(c\),再用\(\sqrt{N-a^2-b^2-c^2}\)确定\(d\)即可。注意,枚举过程中要保证\(0 \leq a \leq b \leq c \leq d\)

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <cstring>
#include <vector>
#include <cmath>
#include <unordered_map>
#include <set>
#include <cmath>
#include <bitset>
using namespace std;
using ll = long long;
const int MAXN = 1e7 + 5;
const int INF = 0x3f3f3f3f;
int mymap[MAXN];
int main() {
int mymax=(int)sqrt(5000000)+1, n;
memset(mymap, 0x3f, sizeof(mymap));
for (int i = 0; i <= mymax; i++) {
for (int j = i; j <= mymax; j++) {
int cur = i * i + j * j;
if (cur >= 1e7) continue;
if (mymap[cur] == INF) mymap[cur] = i;
}
}
while (~(scanf("%d", &n))) {
mymax = (int)sqrt(n) + 1;
for (int a = 0; a <= mymax; a++) {
for (int b = a; b <= mymax; b++) {
int last = n - a * a - b * b; if (last < 0) continue;
if (mymap[last] < INF) {
int c = mymap[last]; //哈希表查询c
int d = (int)(sqrt(last - c * c)); //计算得到d
if(b <= c && c <= d){ //保证顺序
printf("%d %d %d %d\n", a, b, c, d);
a = b = n + 1; //终止循环
}
}
}
}
}
return 0;
}

J. 交换瓶子 #贪心

题意

有\(N\)个瓶子,编号\(1\) ~ \(N\),放在架子上。要求每次拿起2个瓶子,交换它们的位置。经过若干次后,使得瓶子的序号为:\(1\ 2\ 3\ 4\ 5\)。现要你求出最少的交换次数。

分析

注意,该题是求最少交换次数,并不是求逆序对。题目思路与LeetCode 周赛 1536 排布二进制网格的最少交换次数基本一致。不过周赛那题,要求的是降序(本题要求的是升序),要求也更高一些,会出现相同的元素,交换操作只允许相邻行元素交换,在本题中是严格递增且可以任意交换。

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <cstring>
#include <vector>
#include <cmath>
#include <unordered_map>
#include <set>
#include <cmath>
using namespace std;
using ll = long long;
const int MAXN = 1e5 + 5;
int a[MAXN], n;
int main(){
while(~(scanf("%d", &n))){
int ans = 0;
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int i = 1; i <= n; i++){
if(a[i] == i) continue;
int pos = i;
for (int j = i + 1; j <= n; j++){
if(a[j] == i){
pos = j;
break;
}
}
swap(a[i], a[pos]);
ans++;
}
printf("%d\n", ans);
}
return 0;
}

2016年第七届蓝桥杯【C++省赛B组】F、G、H、J 题解的更多相关文章

  1. 2016年第七届蓝桥杯C/C++程序设计本科B组省赛

    /* 2016年第七届蓝桥杯C/C++程序设计本科B组省赛 煤球数目(结果填空) 煤球数目 有一堆煤球,堆成三角棱锥形.具体: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形) ...

  2. 2016年第七届蓝桥杯c/c++省赛B组

    2016年第七届蓝桥杯c/c++省赛B组 声明:以下答案是我自己做的.不能保证正确,须要參考正确答案的请到其它地方找. 第一题 :煤球数目 题目叙述: 有一堆煤球,堆成三角棱锥形.详细: 第一层放1个 ...

  3. 2016第七届蓝桥杯C/C++语言A组

    一:问题: 某君新认识一网友.当问及年龄时,他的网友说:“我的年龄是个2位数,我比儿子大27岁,如果把我的年龄的两位数字交换位置,刚好就是我儿子的年龄” 请你计算:网友的年龄一共有多少种可能情况? 提 ...

  4. 2016年第七届蓝桥杯C/C++程序设计本科B组决赛

    2.答案300 刁丝卫代码,比赛时long long写成int,结果成了263...一等擦肩而过... #include <iostream> #include <fstream&g ...

  5. 2016年第七届蓝桥杯javaB组 试题 答案 解析

    1.煤球数目 有一堆煤球,堆成三角棱锥形.具体: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形), 第四层10个(排列成三角形), .... 如果一共有100层,共有多少个煤 ...

  6. 2016年第七届蓝桥杯C/C++B组省赛题目解析

    题目1:煤球数目 有一堆煤球,堆成三角棱锥形.具体:第一层放1个,第二层3个(排列成三角形),第三层6个(排列成三角形),第四层10个(排列成三角形),....如果一共有100层,共有多少个煤球?请填 ...

  7. 2016年第七届蓝桥杯省赛试题(JavaA组)

    1.结果填空 (满分3分)2.结果填空 (满分5分)3.结果填空 (满分9分)4.代码填空 (满分11分)5.代码填空 (满分13分)6.结果填空 (满分15分)7.结果填空 (满分19分)8.程序设 ...

  8. 2016年第七届蓝桥杯国赛试题(JavaA组)

    1.结果填空 (满分19分)2.结果填空 (满分35分)3.代码填空 (满分21分)4.程序设计(满分47分)5.程序设计(满分79分)6.程序设计(满分99分) 1.阶乘位数 9的阶乘等于:3628 ...

  9. 第七届蓝桥杯个人赛省赛--C语言B组

    题目一 煤球数目 有一堆煤球,堆成三角棱锥形.具体:第一层放1个,第二层3个(排列成三角形),第三层6个(排列成三角形),第四层10个(排列成三角形),....如果一共有100层,共有多少个煤球? 请 ...

随机推荐

  1. 【应用服务 App Service】App Service使用Git部署时,遇见500错误

    问题描述 Azure App Service在部署的时候支持多种方式,如Zip,VS 2019, VS Code,或者是Git部署,当使用Git部署遇见500错误时,可以通过其他的部署方式来验证是否也 ...

  2. 编写shell脚本的规范

    目录 编写shell脚本的一些规范 解释器 添加脚本版本和注释功能 添加脚本调试 变量命名 全局变量和局部变量 命名规范 函数命名 脚本命名 函数 引用模块或文件 脚本日志 配置文件 其他 编写she ...

  3. Bootstrap Blazor 初体验

    自微软去年发布blazor以来,我也一直关注着blazor的动态,从net core 3.1 到 net 5,从 server side 到 wasm client , 点点滴滴印证了 blazor ...

  4. Python使用JsAPI发起微信支付 Demo

    Python使用JsAPI发起微信支付 Demo 这个是基于Django框架. 了解更多,可以关注公众号"轻松学编程" 1.公众号设置.微信商户号设置 这些都可以在官网查得到, 公 ...

  5. 适合 C++ 新手学习的开源项目——在 GitHub 学编程

    作者:HelloGitHub-小鱼干 俗话说:万事开头难,学习编程也是一样.在 HelloGitHub 的群里,经常遇到有小伙伴询问编程语言如何入门方面的问题,如: 我要学习某一门编程语言,有什么开源 ...

  6. go beego框架 入门使用 (一)

    ---恢复内容开始--- 谢谢您花时间读我写的随笔,有问题的话欢迎留言,看到的话都会回复的! beego框架 分为Web版,Api版     api版目录      web版目录      (区别 : ...

  7. 高清DEM最高立减1500元!

    选购攻略: 活动一:选购12.5米DEM(地形)数据.30米 DEM(地形)数据,满500元立减100元.满1000元立减200元.满2000立减500元.满5000元立减1500元:每位用户仅可享受 ...

  8. Javascript的运行效率是原生代码的20%-30%

    所以jser们,写代码更仔细些吧. http://www.cnblogs.com/codemood/p/3213459.html

  9. BATJTMD,大厂招聘,都招什么样Java程序员?

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 Java学到什么程度可以找工作? 最近总看到类似这样的问题,也有一些工作3年左右的小 ...

  10. 基于selenium微博个人主页视频下载

    # -*- coding: utf-8 -*- import selenium from selenium import webdriver import time import urllib.req ...