2018蓝桥杯模拟赛(一)C【模拟】D【dp】E【全排列】F【dfs】
2018-03-27 12:44
441 查看
C.U型数字
最近蒜头君喜欢上了U型数字,所谓U型数字,就是这个数字的每一位先严格单调递减,后严格单调递增。比如 212212212 就是一个U型数字,但是 333333333, 989898, 567567567, 313133131331313,就是不是U型数字。
现在蒜头君问你,[1,100000][1,100000][1,100000] 有多少U型数字?
提示:请不要输出多余的符号。
D LIS
LIS是最长上升子序列。什么是最长上升子序列? 就是给你一个序列,请你在其中求出一段最长严格上升的部分,它不一定要连续。
就像这样:222, 333, 444, 777 和 222, 333, 444, 666 就是序列 222 555 333 444 111 777 666 的两个上升子序列,最长的长度是 444。
E 全排列
相信大家都知道什么是全排列,但是今天的全排列比你想象中的难一点。我们要找的是全排列中,排列结果互不相同的个数。比如:aab 的全排列就只有三种,那就是aab,baa,aba。
代码框中的代码是一种实现,请分析并填写缺失的代码。
思路:填空的地方的意思是,如果i的后面有和s[i] 相等且访问过的字符,则不可以(break),一旦break,j 就不能等于len,就不能继续递归。那么怎么理解这个呢?
先想一下简化的问题吧,假如输入的字符串不重复,例如abcd,那么就是简单的dfs了,一个for循环加一个vis判断,如果判断可以,继续递归。
当有重复的字符时候就比较麻烦了,比如aab,单纯的用递归会输出重复的。那么怎么加上限定条件呢。
这里,我们让重复的这些字符只顺序输出一遍,这样就不会重复
这是什么意思呢,比如说aabc,我们只允许第一个a访问后再访问第二个a,不允许访问第二个,再第一个。
再如,abacda,那三个a只能按顺序访问。
原理是什么呢,用了点高中学的排列组合的知识,先排重复的,例如我们搞abacda这个例子, 先排三个a, 就是 aaa,那么剩下的就相当于直接插入到aaa中,那么如果我们aaa如果按多种顺序排,就会产生多种结果,所以只能按顺序访问。
那么又如何用算法实现呢,直接加个if判断就行了,判断i之后的有没有访问过的且相等的。例如,aabc这个例子,我们第一轮选完之后,到了第二个a,然后进入递归,for循环又从0开始,到了第一个a,然后从这个之后去判断有没有访问过的a,结果判断有,违反了顺序,所以结束。
这个题目的关键也就是排除重复的
蒜头君今天突然开始还念童年了,想回忆回忆童年。他记得自己小时候,有一个很火的游戏叫做数独。便开始来了一局紧张而又刺激的高阶数独。蒜头君做完发现没有正解,不知道对不对? 不知道聪明的你能否给出一个标准答案?
标准数独是由一个给与了提示数字的 9×9网格组成,我们只需将其空格填上数字,使得每一行,每一列以及每一个 3×3 宫都没有重复的数字出现。
输出这个数独得正解,输出格式如下:
2 6 * * * * * *
5 * 2 * * 4
1 * * * * 7
3 * * 2 * 1 8 *
3 * 9 * * *
5 4 * 1 * * 7 *
5 * * * * 1 * * *
6 * * 9 * 7 * * *
7 5 *
把上面的 * 替换成 1−91 - 91−9 就可以了
提醒:两个数字之间要有一个空格,其他地方不要输出多余的符号。
本题答案不唯一,符合要求的答案均正确
最近蒜头君喜欢上了U型数字,所谓U型数字,就是这个数字的每一位先严格单调递减,后严格单调递增。比如 212212212 就是一个U型数字,但是 333333333, 989898, 567567567, 313133131331313,就是不是U型数字。
现在蒜头君问你,[1,100000][1,100000][1,100000] 有多少U型数字?
提示:请不要输出多余的符号。
#include<iostream> #include<cstring> using namespace std; int num[10]; int cnt = 0; int main() { int weishu = 0; int j; int flag; for(int i = 100;i<=99999;i++) { memset(num,0,sizeof(num)); int temp = i; for(j = 0;temp != 0;j++) { num[j] = temp%10; temp = temp/10; } weishu = j; j= 1; while(num[j]<num[j-1]) { j++; } flag = j; while(num[j]>num[j-1]) { j++; } //保证两个循环都进去过才能说明存在严格递减和严格递增 if(j == weishu&&j>flag&&flag!=1) //flag!=1保证进入第一个循环 j>flag 保证进入第二个循环 { cnt++; // cout<<i<<' '; } } cout<<cnt<<endl; }
D LIS
LIS是最长上升子序列。什么是最长上升子序列? 就是给你一个序列,请你在其中求出一段最长严格上升的部分,它不一定要连续。
就像这样:222, 333, 444, 777 和 222, 333, 444, 666 就是序列 222 555 333 444 111 777 666 的两个上升子序列,最长的长度是 444。
#include<iostream> #include<cstring> using namespace std; int f[10000], b[10000]; int lis(int n) { memset(f, 0, sizeof f); int res = 0; for (int i = 0; i < n; ++i) { for (int j = 0; j < i; ++j) { if (b[j] < b[i]) { f[i] = max(f[i],f[j]+1); //填空 dp: 每再前面遇到一个小于自己的数,就判断如果加上这个数那么f[i] = f[j]+1,还是不加上这个数保持f[i],选择大的 } } res = max(res, f[i]); } return res+1; } int main() { int n; scanf("%d", &n); for (int i = 0; i < n; ++i) { scanf("%d", b + i); } printf("%d\n", lis(n)); return 0; }
E 全排列
相信大家都知道什么是全排列,但是今天的全排列比你想象中的难一点。我们要找的是全排列中,排列结果互不相同的个数。比如:aab 的全排列就只有三种,那就是aab,baa,aba。
代码框中的代码是一种实现,请分析并填写缺失的代码。
思路:填空的地方的意思是,如果i的后面有和s[i] 相等且访问过的字符,则不可以(break),一旦break,j 就不能等于len,就不能继续递归。那么怎么理解这个呢?
先想一下简化的问题吧,假如输入的字符串不重复,例如abcd,那么就是简单的dfs了,一个for循环加一个vis判断,如果判断可以,继续递归。
当有重复的字符时候就比较麻烦了,比如aab,单纯的用递归会输出重复的。那么怎么加上限定条件呢。
这里,我们让重复的这些字符只顺序输出一遍,这样就不会重复
这是什么意思呢,比如说aabc,我们只允许第一个a访问后再访问第二个a,不允许访问第二个,再第一个。
再如,abacda,那三个a只能按顺序访问。
原理是什么呢,用了点高中学的排列组合的知识,先排重复的,例如我们搞abacda这个例子, 先排三个a, 就是 aaa,那么剩下的就相当于直接插入到aaa中,那么如果我们aaa如果按多种顺序排,就会产生多种结果,所以只能按顺序访问。
那么又如何用算法实现呢,直接加个if判断就行了,判断i之后的有没有访问过的且相等的。例如,aabc这个例子,我们第一轮选完之后,到了第二个a,然后进入递归,for循环又从0开始,到了第一个a,然后从这个之后去判断有没有访问过的a,结果判断有,违反了顺序,所以结束。
这个题目的关键也就是排除重复的
#include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N=1e3; char str , buf ;//buffer int vis , total, len; void arrange(int num) { if (num == len){ printf("%s\n", buf); total++; return; } for (int i = 0; i < len; ++i) { if (!vis[i]) { int j; for (j = i + 1; j < len; ++j) { //比如递归到buf[1] = if (str[i]==str[j]&&vis[j])//填空 { break; } } if (j == len) { vis[i] = 1; buf[num] = str[i]; arrange(num + 1); vis[i] = 0; } } } } int main() { while (~scanf("%s",str)) { len = strlen(str); sort(str, str + len); total = 0; buf[len] = '\0'; arrange(0); printf("Total %d\n", total); } return 0; }
蒜头君今天突然开始还念童年了,想回忆回忆童年。他记得自己小时候,有一个很火的游戏叫做数独。便开始来了一局紧张而又刺激的高阶数独。蒜头君做完发现没有正解,不知道对不对? 不知道聪明的你能否给出一个标准答案?
标准数独是由一个给与了提示数字的 9×9网格组成,我们只需将其空格填上数字,使得每一行,每一列以及每一个 3×3 宫都没有重复的数字出现。
输出这个数独得正解,输出格式如下:
2 6 * * * * * *
5 * 2 * * 4
1 * * * * 7
3 * * 2 * 1 8 *
3 * 9 * * *
5 4 * 1 * * 7 *
5 * * * * 1 * * *
6 * * 9 * 7 * * *
7 5 *
把上面的 * 替换成 1−91 - 91−9 就可以了
提醒:两个数字之间要有一个空格,其他地方不要输出多余的符号。
本题答案不唯一,符合要求的答案均正确
/* *26****** ***5*2**4 ***1****7 *3**2*18* ***3*9*** *54*1**7* 5****1*** 6**9*7*** ******75* */ #include<iostream> #include<cstdio> using namespace std; int maze[9][9]; void dfs(int pos); int flag = 0; int judge(int x,int y ,int m); int main() { char ch; for(int i = 0;i<9;i++) { for(int j = 0;j<9;j++) { scanf("%c",&ch); if(ch!='*') maze[i][j] = ch-'0'; else if(ch == '*') maze[i][j] = 0; } getchar(); } // for(int i = 0;i<9;i++) // { // for(int j = 0;j<9;j++) // { // cout<<maze[i][j]<<' '; // } // cout<<endl; // } dfs(1); return 0; } void dfs(int pos) { if(flag == 1)return ;//flag的作用是表示找到一个答案即可 就停止递归 if(pos >81) { flag = 1; for(int i = 0;i<9;i++) { for(int j = 0;j<9;j++) { cout<<maze[i][j]<<' '; } cout<<endl; } return ; } //将pos转化成x aed2 y坐标 int x = (pos-1)/9;//当pos == 9 减一再除9还是0 int y = pos%9-1; if(y==-1) y = 8;//在最后一列 if(maze[x][y] == 0) { for(int i = 1;i<=9;i++) { if(judge(x,y,i) == 1) { maze[x][y] = i; dfs(pos+1); maze[x][y] = 0; } } } else dfs(pos+1); } int judge(int x,int y,int m) { for(int i = 0;i<9;i++) { if(maze[x][i] == m) return 0; } for(int i = 0;i<9;i++) { if(maze[i][y] == m) return 0; } for(int i = x / 3 * 3;i < x / 3 * 3 + 3;++i){ for(int j = y / 3 * 3;j < y / 3 * 3 + 3;++j){ if(maze[i][j] == m){ return 0; } } } return 1; }
相关文章推荐
- 蓝桥杯 兰顿蚂蚁(dfs&&模拟)
- 2018_1_31_Palindrome_用的dfs+short_DP
- 蓝桥杯 兰顿蚂蚁 (DFS+模拟)
- jzoj5220 【GDOI2018模拟7.10】C (双序列dp)
- 2018—蓝桥杯B组模拟赛—数列求值
- 蓝桥杯历届试题——带分数(dfs+全排列)
- 蓝桥杯 买不到的数目 (DP&遍历模拟)
- 蓝桥杯模拟赛--康托展开式--全排列(不重复数据)
- 蓝桥杯--历届试题 兰顿蚂蚁 【DFS模拟】
- G题 数列求值-Java_2018 蓝桥杯省赛B组模拟赛(一)
- 2018 蓝桥杯省赛 A 组模拟赛 矩阵求和
- 2018 蓝桥杯省赛 A 组模拟赛 蒜头君下棋
- 2018蓝桥杯模拟赛(一)I【容斥原理】
- 蓝桥杯---数独(模拟 || dfs)
- 计蒜客 2018蓝桥杯模拟赛(一)数独
- 蓝桥杯 兰顿蚂蚁(dfs&&模拟)
- 蓝桥杯 兰顿蚂蚁(dfs&&模拟)
- [BZOJ1072] [SCOI2007] 排列perm - dfs/dp
- 【计蒜客】2018 蓝桥杯省赛 B 组模拟赛(一) —— 结果填空:数独 ---- DFS
- 2018蓝桥杯模拟赛(一)--青出于蓝而胜于蓝(线段树)