ACM 程序设计竞赛入门:第5讲 搜索题
acm搜索入门
int main(){ while(scanf("%d",&n)!=EOF){ memset(vis,0,sizeof(vis));
DFS(1); } return 0; }
}
} }
• DFS-两点是否连通问题 • 题(去年校赛):
• /web/showProblem?id=12 62
不可以! 时间复杂度O(n^2)
• • • • • •
if(sign) break;
} printf("%s\n",sign?"YES":"NO"); } return 0; }
• • • • • • • • • • • • • • • • • • • • • • • •
正确做法: #include<stdio.h> #include<string.h> const int MX=10000+5; int A[MX],vis[1000000+5]; int main(){ int n,i,j,k; while(scanf("%d%d",&n,&k)!=EOF){ memset(vis,0,sizeof(vis)); for(i=1;i<=n;i++){ scanf("%d",&A[i]); vis[A[i]]=1; } sign=false; for(i=1;i<=n;i++){ if(k-A[i]>=0&&vis[k-A[i]]==1){ sign=true; break; } } printf("%s\n",sign?"YES":"NO"); } return 0; }
ACM程序设计基础之搜索
3.搜索的变形
• • • • • • • • 3.1记忆化搜索 3.2迭代加深搜索 3.3双向广度优先搜索 3.4周界搜索 3.5优先队列广搜 3.6A*搜索 3.7IDA*搜索 3.8Alpha-Beta减枝搜索
3.1记忆化搜索
• 记忆化就是在搜索的过程中,对已算出 的节点关键值进行记忆化,以减少下次 再用到此节点时引起的重复搜索。
11
3 层 4 层
2 8 3 1 6 4 7 5
2 8 3 1 6 4 7 5
8 3 2 1 4 7 6 5
2 8 3 7 1 4 6 5
2 8 1 4 3 7 6 5
2 8 3 1 4 5 7 6
1 2 3 7 8 4 6 5
1 2 3 8 4 7 6 5
2 8 3 6 4 1 7 5
2 8 3 1 6 7 5 4
– 扩展结点时,DFS将所有子结点全部扩展出来,再 选取最新的一个结点进行扩展。 – 回溯搜索只扩展所有子结点的其中一个,然后再以 这一子结点去扩展下一个子结点,当某个结点不能 再扩展出新结点的时候,就删除这个结点,用其父 结点来扩展新的结点。 – DFS最后寻找解的路径,回溯搜索路径即解路径 – 占用内存少,只需存取当前的一条搜索路径。 – 要求所有解方案的问题 – 试探性求解问题中
• 标记数组也属于hash的一种 其中hash函数值就是数字本身
DFS的优化
• 如果只求一个可行解,那么找到以后就 可以返回了。 • 判重在有些时候是有必要的。
• 在搜索树上,把一些不可能存在可行解 或者更优解的树枝减掉。
剪枝
• 可行性剪枝 • 最优性剪枝
POJ1011 STICKS
• 已知一些等长的木棍被切成,n个短木棍.现在 要根据这些短木棍的长度来求接原来木棍的 长度,由于可能有多组解,因此 要求求出最短的 可能长度. • 小木棍的个数不超过64 • 如:9 5 2 1 5 2 1 5 2 1 • 原来的可能最短长度为: 6 • 5+1 5+1 5+1 2+2+2
acm编程比赛入门题目集
程序设计比赛试题主办方:迅翔计算机协会最少钱币数:【问题描述】这是一个古老而又经典的问题。
用给定的几种钱币凑成某个钱数,一般而言有多种方式。
例如:给定了6种钱币面值为2、5、10、20、50、100,用来凑15元,可以用5个2元、1个5元,或者3个5元,或者1个5元、1个10元,等等。
显然,最少需要2个钱币才能凑成15元。
你的任务就是,给定若干个互不相同的钱币面值,编程计算,最少需要多少个钱币才能凑成某个给出的钱数。
【要求】【数据输入】输入可以有多个测试用例。
每个测试用例的第一行是待凑的钱数值M(1 <= M <= 2000,整数),接着的一行中,第一个整数K(1 <= K <= 10)表示币种个数,随后是K 个互不相同的钱币面值Ki(1 <= Ki <= 1000)。
输入M=0时结束。
【数据输出】每个测试用例输出一行,即凑成钱数值M最少需要的钱币个数。
如果凑钱失败,输出“Impossible”。
你可以假设,每种待凑钱币的数量是无限多的。
【样例输入】156 2 5 10 20 50 10011 2【样例输出】2ImpossibleFeli 的生日礼物【问题描述】Felicia 的生日是11月1日(和Kitty是同一天生的哦)。
于是Feli请来Kitty一起过生日。
Kitty带来了最新款的“Kitty猫”玩具准备送给Feli,不过她说,这份礼物可不是白送的。
Feli要帮她一个忙,才能够得到心仪已久的玩具。
Kitty说,“Kitty猫”玩具已经卖出了n!个,n<=10^100 *_*,Kitty想知道确切的数字,而不是无聊的“一个数加个感叹号”。
Feli 听了大吃一惊。
要知道,算出n!是一个无比艰巨的任务。
Feli告诉Kitty,就算Feli算出n!,Kitty也看不下去,因为当n=20 时,计算机的长整型已经存不下了(Kitty只能接受1-9之间的数字)。
acm竞赛试题及答案
acm竞赛试题及答案ACM竞赛试题及答案1. 问题描述:给定一个整数数组,找出数组中没有出现的最小的正整数。
2. 输入格式:第一行包含一个整数n,表示数组的长度。
第二行包含n个整数,表示数组的元素。
3. 输出格式:输出一个整数,表示数组中没有出现的最小的正整数。
4. 样例输入:53 4 1 2 55. 样例输出:66. 问题分析:首先,我们需要理解题目要求我们找出数组中缺失的最小正整数。
这意味着我们需要检查数组中的每个元素,并确定最小的正整数是否在数组中。
7. 算法描述:- 遍历数组,使用一个哈希集合记录出现的数字。
- 从1开始,检查每个正整数是否在哈希集合中,直到找到不在集合中的最小正整数。
8. 代码实现:```pythondef find_missing_positive(nums):seen = set()for num in nums:if num <= 0:continuewhile num in seen or num > len(nums):num += 1seen.add(num)return min(set(range(1, len(nums) + 1)) - seen)```9. 测试用例:- 输入:[3, 4, -1, 1]- 输出:210. 答案解析:在给定的测试用例中,数组[3, 4, -1, 1]中没有出现的最小正整数是2。
这是因为-1不是正整数,所以可以忽略。
数组中已经出现了1和3,所以下一个最小的正整数就是2。
11. 注意事项:- 确保数组中的元素是整数。
- 考虑数组中可能包含0或负数的情况。
- 算法的时间复杂度应尽可能低。
12. 扩展思考:- 如果数组非常大,如何优化算法?- 如果数组中的元素可以是浮点数,算法应该如何修改?13. 参考答案:- 针对大数组,可以考虑使用更高效的数据结构,如平衡二叉搜索树。
- 如果元素是浮点数,需要先将其转换为整数,然后再进行处理。
acm大赛试题及答案
acm大赛试题及答案ACM大赛试题及答案1. 题目一:字符串反转问题描述:编写一个程序,输入一个字符串,输出其反转后的字符串。
输入格式:输入包含一个字符串,字符串长度不超过100。
输出格式:输出反转后的字符串。
示例:输入:hello输出:olleh答案:```pythondef reverse_string(s):return s[::-1]input_string = input().strip()print(reverse_string(input_string))```2. 题目二:计算阶乘问题描述:编写一个程序,输入一个非负整数n,输出n的阶乘。
输入格式:输入包含一个非负整数n,n不超过20。
输出格式:输出n的阶乘。
示例:输入:5输出:120答案:```pythondef factorial(n):if n == 0:return 1else:return n * factorial(n - 1)n = int(input())print(factorial(n))```3. 题目三:寻找最大数问题描述:给定一个包含n个整数的数组,找出数组中的最大数。
输入格式:输入包含一个整数n,表示数组的大小,随后是n个整数。
输出格式:输出数组中的最大数。
示例:输入:5 1 2 3 4 5输出:5答案:```pythonn = int(input())numbers = list(map(int, input().split()))max_number = max(numbers)print(max_number)```4. 题目四:判断闰年问题描述:编写一个程序,输入一个年份,判断该年份是否为闰年。
输入格式:输入包含一个整数,表示年份。
输出格式:如果输入的年份是闰年,则输出"Yes",否则输出"No"。
示例:输入:2000输出:Yes答案:```pythonyear = int(input())if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):print("Yes")else:print("No")```5. 题目五:斐波那契数列问题描述:编写一个程序,输入一个非负整数n,输出斐波那契数列的第n项。
ACM 程序设计竞赛入门:第5讲 搜索题
2020/12/10
17
深入分析
p,q的范围其实可在2—50000(why?) 然而,这是最小的范围吗?
考虑大于10000的某个质数,不妨设为Q,另一 个质数为P,则:
如果P<10,P/Q<0.001 如果P>10,P*Q>100000
而考虑到a,b的取值范围(1<=a<=b<=1000) 可知min(a/b)=0.001
1.先访问左子树 2.再访问右子树 3.最后访问根结点 4.对于左右子树的访问也要满足以上规则
示例如下:
2020/12/10
26
1
2
3
4
56
7
以上二叉树的后根遍历序列是:??
4、5、 2、 6、7 、 3、 1
2020/12/10
27
(4)层次遍历
对树的访问次序是:
1.先访问根结点 2.再访问根结点的子节点(即第二层节点) 3.再访问第三层节点
同时,要求: p*q<=m<=100000
所以无论如何质数都不能超过10000。(事实上,
不会超过9091)
2020/12/10
18
搜索时的技巧:
搜索顺序很重要。建议从大往小搜 ( num:质数的个数 ) for (i=num-1;i>=0;i--) for (j=i;j<=num-1;j++) ……
(6)若后继节点中某一个是目标节点,则找 到一个解,成功退出。否则转向(2)循环。
2020/12/10
41
例、节点搜索示意图
OPEN
S
CLOSED
S
A, H,
A
R, F,
acm竞赛试题及答案
acm竞赛试题及答案ACM(Association for Computing Machinery)竞赛是一项全球性计算机科学竞赛,旨在锻炼参赛者的问题解决能力和编程技巧。
每年都有数千名来自不同学校的学生参加这一挑战。
本文将提供一些最近的ACM竞赛试题以及相应的答案,帮助读者了解和学习竞赛题目的类型和解题思路。
1. 问题描述给定一个由N个整数组成的数组A,请编写一个程序,找出数组中两个不同元素的差的最小值。
2. 输入格式- 第一行包含一个整数N,表示数组A的长度。
- 第二行包含N个以空格分隔的整数,表示数组A中的元素。
3. 输出格式输出一个整数,表示数组中两个不同元素的差的最小值。
4. 示例输入:51 52 9 12输出:15. 解题思路该问题可以通过对数组进行排序,并比较相邻两个数的差值来求解。
首先,将数组A进行升序排序。
然后,遍历排序后的数组,依次计算相邻两个数的差值,并记录其中的最小值。
最后,返回这个最小差值即可。
6. 代码实现```pythondef min_difference(nums):nums.sort() # 对数组进行升序排序min_diff = float('inf') # 初始化最小差值为正无穷大for i in range(len(nums)-1):diff = abs(nums[i] - nums[i+1]) # 计算相邻两个数的差值min_diff = min(min_diff, diff) # 更新最小差值return min_diff# 输入处理N = int(input())A = list(map(int, input().split()))# 调用函数并输出结果result = min_difference(A)print(result)```7. 答案解析对给定的数组进行排序后,遍历数组计算相邻两个数的差值,并记录其中的最小值。
上述代码中,首先将数组A进行升序排序,然后使用一个变量`min_diff`来记录最小差值。
入门acm试题及答案
入门acm试题及答案入门ACM试题及答案1. 问题描述给定一个整数数组,请找出数组中第二大的数。
2. 输入格式第一行包含一个整数n,表示数组的大小。
第二行包含n个整数,表示数组元素。
3. 输出格式输出数组中第二大的数。
4. 样例输入53 14 1 55. 样例输出46. 问题分析首先,我们需要读取数组的大小和元素。
然后,使用两个变量分别存储数组中的最大值和第二大的值。
遍历数组,更新这两个变量的值。
7. 算法实现```pythondef find_second_max(n, arr):max_val = float('-inf')second_max = float('-inf')for num in arr:if num > max_val:second_max = max_valmax_val = numelif num > second_max and num != max_val:second_max = numreturn second_max# 读取输入n = int(input())arr = list(map(int, input().split()))# 输出结果print(find_second_max(n, arr))```8. 注意事项- 确保数组中至少有两个不同的元素。
- 考虑数组中可能存在相等的最大值的情况。
9. 测试用例- 输入:`5 3 1 4 1 5`,输出:`4`- 输入:`4 10 10 20 20`,输出:`10`- 输入:`3 7 5 3 5`,输出:`5`10. 总结本题考查了基本的数组操作和简单的逻辑判断,通过维护两个变量来跟踪最大值和第二大的值,可以高效地解决问题。
ACM竞赛基础训练题.docx
ACM竞赛基础训练题H【题目]】N皇后问题(八皇后问题的扩展)【题ri 2】排球队员站位问题【题H 3]把自然数N分解为若干个自然数之和。
【题H 4]把自然数N分解为若干个自然数之积。
【题H 5】马的遍历问题。
【题H 6】加法分式分解【题H 7】地图着色问题【题H 8]在n和的正方形屮放置长为2,宽为1的长条块,【题H 9】找迷宫的最短路径。
(广度优先搜索算法)【题Fl 10]火车调度问题【题H 11]农夫过河【题FI 12]七段数码管问题。
【题H 13]把1-8这8个数放入下图8个格中,要求相邻的格(横,竖,对角线)上填的数不连续. 【题FI 14]在4X4的棋盘上放置8个棋,要求每一行,毎一列上只能放置2个.【题H 15]迷宫问题.求迷宫的路径.(深度优先搜索法)【题H 16]一笔画问题【题H 17]城市遍历问题.【题H 18]棋子移动问题【题H 19]求集合元索问题(l,2x+l,3X+l类)【题RI N皇后问题(含八皇后问题的扩展,规则同八皇后):在N粒的棋盘上, 放置N个皇后,要求每一横行每一列,每一对角线上均只能放置一个皇后,问可能的方案及方案数。
const max=8;var i,j:integer;a: array [1.. max] of 0.. max; {放皇后数组}b:array[2.. 2*max] of boolean; {/对角线标志数组}c:array[-(max-1).. max-1 ] of boolean; {\对角线标志数组}col:array [1.. max] of boolean; {列标志数组}total: integer; {统计总数}procedure output; {输出}var i:inte^er;beginwrite (' No.' :4,' [', total+1:2,']');for i :=1 to max do write (a [i] :3) ;write(, ');if (to tal+1) mod 2 =0 t hen writ eln; inc (to tai);end;function ok(i, dep: integer) :boolean; {判断第dep 行第i 列可放否}begin ok:=false;if ( b[i+dep]二true) and ( c[dep-i]二true) {and (a[dep]=0)} and(col[i]=true) then ok:二trueend;procedure try (dep:integer);var i,j:integer;beginfor i:=l to max do 侮一行均有max种放法}i f ok (i, dep) then begi na [dep]:=i;b[i+dep]:二false; {/对角线已放标志}c[dep-i]:二false; {\对角线已放标志}col [i]:二false; {列已放标志}if dep二max then outputelse try (dep+1) ; {递归下一层}a[dep] :=0; {取走皇后,回溯}b[i+dep]:二true; {恢复标志数组}c[dep-i]:二true;col[i]:二true;end;end;beginfor i:=1 to max do begin a[i]:=0;col[i]:=true;end;for i:=2 to 2*max do b[i]:二true;for i:=-(max-1) to max~l do c[i]:=true;total:二0;try(l); writelntotal , total);end.【测试数据】n二8八皇后问题No.[ 1] 1 5 8 6 3 7 2 4 No. [ 2] 1 6 83 7 4 2 5 No.[ 3] 1 7 4 6 8 2 5 3 No. [ 4] 1 7 58 2 4 6 3 No.[ 5] 2 4 6 8 3 1 7 5 No. [ 6] 2 5 71 3 8 6 4 No.[ 7] 2 5 7 4 1 8 6 3 No. [ 8] 2 6 17 4 8 3 5 No.[ 9] 2 6 8 3 1 4 7 5 No. [10] 2 7 36 8 5 1 4No. [11] 2 7 5 8 1 4 6 3 No. [12] 2 8 61 3 5 7 4 No. [13] 3 1 7 5 8 2 4 6 No. [14] 3 5 28 1 7 4 6 No. [15] 3 5 2 8 6 4 7 1 No. [16] 3 5 71 4 2 8 6 No. [17] 3 5 8 4 1 7 2 6 No. [18] 3 6 25 8 1 7 4 No. [19] 3 6 2 7 1 4 8 5 No. [20] 3 6 27 5 1 8 4 No. [21] 3 6 4 1 8 5 7 2 No. [22] 3 6 42 8 5 7 1 No. [23] 3 6 8 1 4 7 5 2 No. [24] 3 6 81 5 7 2 4 No. [25] 3 6 8 2 4 1 7 5 No. [26] 3 7 28 5 1 4 6 No. [27] 3 7 2 8 6 4 1 5 No. [28] 3 8 47 1 6 2 5 No. [29] 4 1 5 8 2 7 3 6 No. [30] 4 1 58 6 3 7 2 No. [31] 4 2 5 8 6 1 3 7 No. [32] 4 2 73 6 8 1 5 No. [33] 4 2 7 3 6 8 5 1 No. [34] 4 2 75 1 8 6 3 No. [35] 4 2 8 5 7 1 3 6 No. [36] 4 2 86 1 3 5 7 No. [37] 4 6 1 5 2 8 3 7 No. [38] 4 6 82 7 1 3 5 No. [39] 4 6 8 3 1 7 5 2 No. [40] 4 7 18 5 2 6 3 No. [41] 47 3 8 2 5 1 6 No. [42] 4 7 52 6 1 3 8 No. [43] 4 7 5 3 1 6 8 2 No. [44] 4 8 13 6 2 7 5 No. [45] 4 8 1 5 7 2 6 3 No. [46] 4 8 53 1 7 2 6 No. [47] 5 1 4 6 8 2 7 3 No. [48] 5 1 84 2 7 3 6 No. [49] 5 1 8 6 3 7 2 4 No. [50] 5 2 46 8 3 1 7 No. [51] 5 2 47 3 8 6 1 No. [52] 5 2 61 7 48 3 No. [53] 5 2 8 1 47 3 6 No. [54] 5 3 16 8 2 4 7 No. [55] 5 3 1 7 28 6 4 No. [56] 5 3 84 7 1 6 2 No. [57] 5 7 1 3 8 6 4 2 No. [58] 5 7 14 2 8 6 3 No. [59] 5 7 2 4 8 1 3 6 No. [60] 5 7 26 3 1 4 8 No. [61] 5 7 2 6 3 1 8 4 No. [62] 5 7 41 3 8 6 2 No. [63] 5 8 4 1 3 6 2 7 No. [64] 5 8 41 7 2 6 3 No. [65] 6 1 5 2 8 3 7 4 No. [66] 6 2 71 3 5 8 4 No. [67] 6 2 7 1 4 8 5 3 No. [68] 6 3 17 5 8 2 4 No. [69] 6 3 1 8 4 2 7 5 No. [70] 6 3 18 5 2 4 7 No. [71] 6 3 5 7 1 4 2 8 No. [72] 6 3 58 1 4 2 7 No. [73] 6 3 7 2 48 1 5 No. [74] 6 3 72 8 5 1 4 No. [75] 6 3 7 4 1 8 2 5 No. [76] 6 4 15 8 2 7 3 No. [77] 6 4 2 8 5 7 1 3 No. [78] 6 4 71 3 5 2 8 No. [79] 6 4 7 1 8 2 5 3 No. [80] 6 8 24 1 7 5 3 No. [81] 7 1 3 8 6 4 2 5 No. [82] 7 2 41 8 5 3 6 No. [83] 7 2 6 3 1 4 8 5 No. [84] 7 3 16 8 5 2 4 No. [85] 7 3 8 2 5 1 6 4 No. [86] 7 4 25 8 1 3 6 No. [87] 7 4 2 8 6 1 3 5 No. [88] 7 5 31 6 8 2 4 No. [89] 8 2 4 1 7 5 3 6 No. [90] 8 2 53 1 7 4 6 No. [91] 8 3 1 6 2 5 7 4 No. [92] 8 4 13 6 2 7 5 total:92 对于N皇后:【题H 】排球队员站位问题I ----------------- 1图为排球场的平面图,其屮一、二、三、四、五、六为位 置编号, I |二、三、四号位置为前排,一、六、五号位为后排。
acm基础试题及答案
acm基础试题及答案ACM基础试题及答案1. 以下哪个选项是C语言中正确的字符串声明方式?A. char str[] = "Hello World";B. char str[10] = "Hello World";C. string str = "Hello World";D. char str = "Hello World";答案:A2. 在C++中,以下哪个关键字用于定义类的私有成员?A. publicB. privateC. protectedD. static答案:B3. 以下哪个数据结构允许快速随机访问元素?A. 链表B. 队列C. 数组D. 栈答案:C4. 在Python中,以下哪个函数用于将列表中的元素连接成一个字符串?A. join()B. concat()C. append()D. merge()答案:A5. 在数据库管理系统中,SQL代表什么?A. Structured Query LanguageB. Standard Query LanguageC. Simple Query LanguageD. System Query Language答案:A6. 在HTML中,用于定义最重要的标题的标签是什么?A. <h1>B. <title>C. <header>D. <h6>答案:A7. 在JavaScript中,以下哪个方法用于将字符串转换为小写?A. toUpperCase()B. toLowerCase()C. toUpperCase()D. toCamelCase()答案:B8. 在Unix/Linux系统中,哪个命令用于查看当前目录下的文件和文件夹?A. lsB. pwdC. cdD. mkdir答案:A9. 在C语言中,以下哪个函数用于计算数组中元素的总和?A. sum()B. count()C. sizeof()D. memset()答案:A10. 在Java中,以下哪个关键字用于创建单例模式?A. staticB. finalC. synchronizedD. volatile答案:A。
ACMHPU第五讲_贪心算法(1)实训
实训讲解二
有一些矩形(N个 ,长和宽分别为Li和 有一些矩形 个),长和宽分别为 和 Wi(0<i<=N) 所有的矩形都得放入到特别的容器里面一个容器 最多可以容纳一个矩形 但是, 但是,每个矩形里面可以放一个长和宽都不比自 己大的矩形 问最少需要多少个容器
问题转化
每个矩形可以用一个二元组来表示, 每个矩形可以用一个二元组来表示,那么就可以 表示为二维坐标系上的一个点 问题就变成了最少要找多少条只能向上和向右走 的线通过所有点。 的线通过所有点。
例: N=3 L1=3,L2=2,L3=2 L=4
则至少需要两块木板(如 则至少需要两块木板 如 右图) 右图
算法提出
每一个区域都需要有至少一块木板完全覆盖 首先考虑一块木板怎么放 覆盖最左边几个区域的木板, 覆盖最左边几个区域的木板,左边界对齐第一个 区域的左边界可以覆盖最多的区域 这块木板选择完了之后, 这块木板选择完了之后,已经被完全覆盖了的区 域可以不管了, 域可以不管了,剩下的依然如上选择下一块木板 的位置 这样是对的么? 这样是对的么?
正确性证明
Ai (1<=i<=N) 表示从第 块区域到第 块区 表示从第i块区域到第 块区域到第N块区 域所需要的最少木板数量, 域所需要的最少木板数量,则Ai>=Aj (i<j) A1就是这个题目的答案 就是这个题目的答案 A1=min(Ai + 1 | A1+A2+……+Ai1<=L) 所以如果要得到A1, 所以如果要得到 ,就需要选择最大的满足条 件的i所以第一块木板的左边界需要与第一个区 件的 所以第一块木板的左边界需要与第一个区 域的左边界对齐 算法正确! 算法正确!
实训思考
一个晚上有N个人想要过一个独木桥 一个晚上有 个人想要过一个独木桥 各个人通过这个独木桥需要时间为Ti 各个人通过这个独木桥需要时间为 晚上,需要手电筒照明, 晚上,需要手电筒照明,但是手电筒只有一个 独木桥每次只允许两个人通过, 独木桥每次只允许两个人通过,需要的时间和速 度慢的人通过独木桥的时间相同 问最少需要多长时间才能使所有的人通过独木桥
ACM必做50题的解题-快速查找 (B-Search, Hash and so on)
if(r[x]>r[y])
p[y]=x;
else if(r[x]<r[y])
p[x]=y;
else
{
r[y]++;
char fn[11];
}dict;
dict a[100001];
/* 定义qsort比较函数 */
int q_cmp(const void * a,const void *b)
{
return strcmp(((dict*)a)->fn, ((dict*)b)->fn);
int i, sign;
dict *p;
i = 0;
/* 查询标记记为"未开始" */
sign = 1;
/* 读取字符串直到文件结束 */
while(gets(str))
/* 找到则输出结果 */
if (p)
{
puts(p->en);
}
int id2 = search(s2,root);
degree[id1]++;
degree[id2]++;
if(p[id1]==0)
make_set(id1);
p->next[s[i]-'a']=new TreeNode;
p=p->next[s[i]-'a'];
}
if(p->id==0)//first insert
#include <cstring>
using namespace std;
const int max_size=500001;
ACM必做50题的解题-搜索
POJ1011 Sticks 搜索+强剪枝这个题目是不是贪心的,我就是第一次用了贪心,一直W A,相当的悲剧,贪心错误的sample:7 15 11 8 8 8 4 3 2 1,所以大家还是全部搜索。
但是全部搜索必须剪枝,不然肯定是TLE的,而且本体属于强剪枝,少剪了也是TLE。
经典搜索题,果然是到处充斥着剪枝才能过啊,我的代码离剪到极限还差很多题目给出一大堆小棍子的长度,需要把他们拼成几根长度相等的大棍子,求大棍子的最短长度看自己剪枝方法的效果时候,可以添设一个变量来记录递归次数如剪枝4:没有这个剪枝的情况下对以下数据需要40万次递归,而加上这个剪枝后减少到了4万多次对数据:4515 3 2 4 11 1 8 8 8 15 3 2 4 11 1 8 8 8 15 3 2 4 11 1 8 8 8 15 3 2 4 11 1 8 8 8 15 3 2 4 11 1 8 8 8#include <iostream>#include <algorithm>using namespace std;int sticks[65];int used[65];int n,len;bool dfs(int i,int l,int t)//i为当前试取的棍子序号,l为要拼成一根完整的棍子还需要的长度,t初值为所有棍子总长度{if(l==0){t-=len;if(t==0)return true;for(i=0;used[i];++i); //剪枝1:搜索下一根大棍子的时候,找到第一个还没有使用的小棍子开始used[i]=1; //由于排序过,找到的第一根肯定最长,也肯定要使用,所以从下一根开始搜索if(dfs(i+1,len-sticks[i],t))return true;used[i]=0;t+=len;}{for(int j=i;j<n;++j){if(j>0&&(sticks[j]==sticks[j-1]&&!used[j-1])) //剪枝2:前后两根长度相等时,如果前面那根没被使用,也就是由前面那根continue; //开始搜索不到正确结果,那么再从这根开始也肯定搜索不出正确结果,此剪枝威力较大if(!used[j]&&l>=sticks[j]) //剪枝3:最简单的剪枝,要拼成一根大棍子还需要的长度L>=当前小棍子长度,才能选用{l-=sticks[j];used[j]=1;if(dfs(j,l,t))return true;l+=sticks[j];used[j]=0;if(sticks[j]==l) //剪枝4:威力巨大的剪枝,程序要运行到此处说明往下的搜索失败,若本次的小棍长度刚好填满剩下长度,但是后break; //面的搜索失败,则应该返回上一层}}}return false;}bool cmp(const int a, const int b){return a>b;}int main(){while(cin>>n&&n){int sum=0;for(int i=0;i<n;++i){cin>>sticks[i];sum+=sticks[i];used[i]=0;}sort(sticks,sticks+n,cmp); //剪枝5:从大到小排序后可大大减少递归次数bool flag=false;for(len=sticks[0];len<=sum/2;++len) //剪枝6:大棍长度一定是所有小棍长度之和的因数,且最小因数应该不小于小棍中最长的长度{if(sum%len==0){if(dfs(0,len,sum)){flag=true;cout<<len<<endl;break;}}}if(!flag)cout<<sum<<endl;}return 0;}poj 1033 Defragment题意:磁盘整理,按照从第一个文件到最后一个文件的顺序排放,而且每个文件的碎片按原来的顺序放在一起,要求转移的次数最少。
acm基础试题及答案
acm基础试题及答案1. 题目:给定一个整数数组,请找出数组中第二大的数。
答案:我们可以使用排序的方法,将数组从小到大排序,然后数组中的倒数第二个数就是第二大的数。
或者使用一次遍历的方法,首先初始化两个变量,一个用来存储最大值,一个用来存储第二大的值。
遍历数组,每次比较当前元素与最大值,如果当前元素大于最大值,则更新第二大的值为最大值,并将当前元素赋给最大值;如果当前元素小于最大值但大于第二大的值,则更新第二大的值。
2. 题目:实现一个函数,计算一个字符串中字符出现的次数。
答案:可以使用哈希表来实现,遍历字符串中的每个字符,将其作为键值对存储在哈希表中,键是字符,值是该字符出现的次数。
遍历结束后,哈希表中存储的就是每个字符出现的次数。
3. 题目:给定一个链表,删除链表的倒数第n个节点,并且返回新的链表头节点。
答案:可以使用双指针的方法,首先初始化两个指针,都指向链表的头节点。
然后移动第一个指针,移动n步,此时第一个指针指向倒数第n个节点的前一个节点。
接着同时移动两个指针,直到第一个指针到达链表的末尾,此时第二个指针指向的节点就是需要删除的节点的前一个节点。
然后更新第二个指针的next指针,使其指向第二个指针的next节点的next节点,最后返回链表的头节点。
4. 题目:编写一个函数,判断一个整数是否是回文数。
回文数是指正序和倒序读都一样的数。
答案:首先将整数转换为字符串,然后使用双指针的方法,一个指针从字符串的开始位置,一个指针从字符串的结束位置,向中间移动。
如果两个指针指向的字符不相等,则该整数不是回文数。
如果遍历结束后没有发现不相等的字符,则该整数是回文数。
5. 题目:给定一个字符串,找出其中不含有重复字符的最长子串的长度。
答案:可以使用滑动窗口的方法,维护一个哈希表记录窗口内字符的出现情况,以及一个变量记录不含有重复字符的最长子串的长度。
遍历字符串,每次移动窗口的右端点,如果当前字符不在窗口内,则更新最长子串的长度,并将字符添加到哈希表中。
ACM入门题(北大oj)
1000#include<stdio.h>int main(){int a,b,c;while(scanf("%d%d",&a,&b)!=EOF){c=a+b;printf("%d\n",c);}}1067#include<stdio.h>#include<math.h>#include<stdlib.h>int main(){int a,b;while(scanf("%d%d",&a,&b)!=EOF){if(a>b){int t=a;a=b;b=t;}int k=b-a;int a0=(int)(k*(1+sqrt(5.0))/2);if(a0==a) printf("0\n");else printf("1\n");}}1080#include<stdio.h>#include<stdlib.h>int a[5][5]={5,-1,-2,-1,-3,-1,5,-3,-2,-4,-2,-3,5,-2,-2,-1,-2,-2,5,-1,-3,-4,-2,-1,0};int main(){int ca;scanf("%d",&ca);while(ca--){int n,m,i,j,max[105][105],b[105],d[105];char s[105],c[105];scanf("%d%s",&n,s);scanf("%d%s",&m,c);for(i=1;i<=n;i++){if(s[i-1]=='A') b[i]=0;if(s[i-1]=='C') b[i]=1;if(s[i-1]=='G') b[i]=2;if(s[i-1]=='T') b[i]=3;}for(i=1;i<=m;i++){if(c[i-1]=='A') d[i]=0;if(c[i-1]=='C') d[i]=1;if(c[i-1]=='G') d[i]=2;if(c[i-1]=='T') d[i]=3;}max[0][0]=0;for(i=1;i<=n;i++)max[i][0]=max[i-1][0]+a[b[i]][4];for(i=1;i<=m;i++)max[0][i]=max[0][i-1]+a[4][d[i]];for(i=1;i<=n;i++)for(j=1;j<=m;j++){max[i][j]=max[i-1][j-1]+a[b[i]][d[j]];if(max[i-1][j]+a[b[i]][4]>max[i][j])max[i][j]=max[i-1][j]+a[b[i]][4];if(max[i][j-1]+a[4][d[j]]>max[i][j])max[i][j]=max[i][j-1]+a[4][d[j]];}printf("%d\n",max[n][m]);}}1013#include<stdio.h>#include<algorithm>#include<math.h>#include<stdlib.h>#define PI 3.141592653using namespace std;struct point{double x;double y;}p[30005],res[30005];int cmp(point p1,point p2){return p1.y<p2.y||(p1.y==p2.y&&p1.x<p2.x);}bool ral(point p1,point p2,point p3){if((p2.x-p1.x)*(p3.y-p1.y)<=(p2.y-p1.y)*(p3.x-p1.x)) return true;return false;}double dis(point p1,point p2){return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));}int main(){int n,m;while(scanf("%d%d",&n,&m)!=EOF){int i,j;for(i=0;i<n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);sort(p,p+n,cmp);res[0]=p[0];res[1]=p[1];int top=1;for(i=2;i<n;i++){while(top&&ral(res[top-1],res[top],p[i]))top--;res[++top]=p[i];}int len=top;res[++top]=p[n-2];for(i=n-3;i>=0;i--){while(top!=len&&ral(res[top-1],res[top],p[i]))top--;res[++top]=p[i];}double t=0;for(i=0;i<top;i++)t=t+dis(res[i],res[i+1]);printf("%.lf\n",t+2*PI*m);}}1149#include<iostream>#include<cstring>using namespace std;#define inf 0x5fffffffint a[105][105],f[1005],ct[1005],pre[205],n,m,q[105]; int bfs(){int flow=inf,qh=0,qe=1,i;memset(pre,-1,sizeof(pre));q[1]=0;pre[0]=-1;while(qh<qe){int t=q[++qh];for(i=1;i<=n+1;i++)if(pre[i]==-1&&a[t][i]>0){pre[i]=t;if(a[t][i]<flow) flow=a[t][i];if(i==n+1) return flow;q[++qe]=i;}}return -1;}void maxflow(){int res=0,ans,t;while((ans=bfs())!=-1){res=res+ans;t=n+1;while(t)a[pre[t]][t]-=ans;a[t][pre[t]]+=ans;t=pre[t];}}printf("%d\n",res);}int main(){while(scanf("%d%d",&m,&n)!=EOF){memset(f,-1,sizeof(f));memset(a,0,sizeof(a));int i,j,k,t;for(i=1;i<=m;i++)scanf("%d",&ct[i]);for(i=1;i<=n;i++){scanf("%d",&k);for(j=1;j<=k;j++){scanf("%d",&t);if(f[t]!=-1) a[f[t]][i]=inf;else a[0][i]=a[0][i]+ct[t];f[t]=i;}scanf("%d",&k);a[i][n+1]=k;}maxflow();}}1157#include<stdio.h>#include<stdlib.h>int a[105][105],b[105][105];int main(){int max(int x,int y);int n,m;while(scanf("%d%d",&n,&m)!=EOF){for(i=1;i<=n;i++)for(j=1;j<=m;j++)scanf("%d",&a[i][j]);b[1][1]=a[1][1];for(i=2;i<=m-n+1;i++){if(a[1][i]<b[1][i-1]) b[1][i]=b[1][i-1];else b[1][i]=a[1][i];}for(i=2;i<=n;i++)for(j=i;j<=i+m-n;j++){a[i][j]=a[i][j]+b[i-1][j-1];if(i==j) b[i][j]=a[i][j];else{if(a[i][j]>b[i][j-1]) b[i][j]=a[i][j];else b[i][j]=b[i][j-1];}}printf("%d\n",b[n][m]);}}1200#include<stdio.h>#include<string.h>bool flag[20000000];int a[300];char s[20000000];int main(){int n,m;while(scanf("%d%d",&n,&m)!=EOF){memset(flag,0,sizeof(flag));scanf("%s",s);int i,j=0,len=strlen(s);memset(a,0,sizeof(a));for(i=0;i<len;i++)a[s[i]]=1;for(i=0;i<256;i++)if(a[i]==1) a[i]=j++;int mod=1,res=0;for(i=0;i<n-1;i++)mod=mod*m;for(i=0;i<n;i++)res=res*m+a[s[i]];flag[res]=1;for(i=n;i<len;i++){res=res%mod*m+a[s[i]];flag[res]=1;}int count=0;mod=mod*m;for(i=0;i<=mod;i++)if(flag[i]==1) count++;printf("%d\n",count);}}1207#include<stdio.h>#include<stdlib.h>int main(){int b,c,i,j,max=0,k,t,r;while(scanf("%d%d",&b,&c)!=EOF){if(b>c){t=b;r=c;}else{t=c;r=b;}max=0;for(i=r;i<=t;i++){j=1;k=i;while(k!=1){j++;if(k%2==0) k=k/2;else k=3*k+1;}if(j>max) max=j;}printf("%d %d %d\n",b,c,max);}//system("pause");}1273#include<iostream>#include<cstring>#include<queue>using namespace std;#define inf INT_MAXint n,m,a[205][205],pre[205],lev[205],num[205]; void bfs(){queue<int>Q;memset(lev,-1,sizeof(lev));memset(num,0,sizeof(num));Q.push(n);lev[n]=0;num[0]=1;while(!Q.empty()){int t=Q.front(),i;Q.pop();for(i=1;i<=n;i++)if(lev[i]==-1&&a[i][t]>0){lev[i]=lev[t]+1;num[lev[i]]++;Q.push(i);}}}int maxflow(){int flow=0,i,ans,cur=1;bfs();while(lev[cur]<n){if(cur==n){ans=inf;while(cur!=1){if(a[pre[cur]][cur]<ans) ans=a[pre[cur]][cur];cur=pre[cur];}cur=n;while(cur!=1){a[pre[cur]][cur]-=ans;a[cur][pre[cur]]+=ans;cur=pre[cur];}flow=flow+ans;}for(i=1;i<=n;i++)if(a[cur][i]>0&&lev[cur]==lev[i]+1){pre[i]=cur;cur=i;break;}if(i>n){lev[cur]=n+1;num[lev[cur]]--;if(num[lev[cur]]==0) break;for(i=1;i<=n;i++)if(a[cur][i]>0&&lev[i]+1<lev[cur]) lev[cur]=lev[i]+1;num[lev[cur]]++;if(cur!=1) cur=pre[cur];}}return flow;}int main(){while(scanf("%d%d",&m,&n)!=EOF){int i,j;memset(a,0,sizeof(a));for(i=0;i<m;i++){int b,c,d;scanf("%d%d%d",&b,&c,&d);a[b][c]+=d;}printf("%d\n",maxflow());}}1285#include<stdio.h>#include<string.h>int num[55];unsigned __int64 f[55][55];int main(){int n,m,ct=0;while(scanf("%d%d",&n,&m)!=EOF){if(n==0&&m==0) break;int i,j,a,k;memset(num,0,sizeof(num));for(i=0;i<n;i++){scanf("%d",&a);num[a]++;}memset(f,0,sizeof(f));f[0][0]=1;for(i=0;i<50;i++)for(j=0;j<=50;j++)for(k=0;k<=num[i+1];k++)f[i+1][j+k]=f[i+1][j+k]+f[i][j];printf("Case %d:\n",++ct);for(i=0;i<m;i++){scanf("%d",&a);printf("%I64d\n",f[50][a]);}}}1364#include <iostream>#include <queue>#include <cstring>using namespace std;int v[105],pre[105],w[105],h[105],flag[105],ct[105],d[105],n,m,num; void add(int a,int b,int c){v[num]=b;pre[num]=h[a];w[num]=c;h[a]=num++;}bool spfa(){int i;queue<int> Q;for(i=0;i<=n;i++){Q.push(i);flag[i]=1;d[i]=0;}while(!Q.empty()){int t=Q.front();Q.pop();flag[t]=0;for(i=h[t];i>=0;i=pre[i]){int p=v[i];if(d[t]+w[i]<d[p]){d[p]=d[t]+w[i];ct[p]++;if(flag[p]==0){Q.push(p);flag[p]=1;}}if(ct[p]>n) return false;}}return true;}int main(){while(cin>>n){if(n==0) break;cin>>m;int a,b,c;char s[3];num=0;memset(flag,0,sizeof(flag));memset(ct,0,sizeof(ct));memset(h,-1,sizeof(h));for(int i=1;i<=m;i++){cin>>a>>b>>s>>c;if(strcmp(s,"gt")==0) add(a-1,a+b,-1-c);else add(a+b,a-1,c-1);}if(spfa()) cout<<"lamentable kingdom"<<endl;else cout<<"successful conspiracy"<<endl;}return 0;}1384#include<stdio.h>#include<stdlib.h>int b[10005],a[600][2];int main(){int ca;scanf("%d",&ca);while(ca--){int M1,M2,M,n,i,j,value;scanf("%d%d",&M1,&M2);M=M2-M1;scanf("%d",&n);for(i=0;i<n;i++)scanf("%d%d",&a[i][0],&a[i][1]);for(i=0;i<=M;i++)b[i]=-1;b[0]=0;for(i=0;i<n;i++)for(j=0;j+a[i][1]<=M;j++)if(b[j]!=-1){value=b[j]+a[i][0];if(value<b[j+a[i][1]]||b[j+a[i][1]]==-1)b[a[i][1]+j]=value;}if(b[M]==-1) printf("This is impossible.\n");elseprintf("The minimum amount of money in the piggy-bank is %d.\n",b[M]);}}1473#include<stdio.h>#include<math.h>#include<stdlib.h>#include<string.h>int main(){char S[300],c[300][100];int count1=0;while(scanf("%s",S)!=EOF){if(strcmp(S,"END")==0) break;int len=strlen(S),i,count=0,j=0,d;for(i=0;i<len;i++){if(S[i]!=','&&S[i]!='.'){c[count][j]=S[i];j++;}else{c[count][j]='\0';j=0;count++;}}int nw=0,ne=0,sw=0,se=0,n=0,s=0,e=0,w=0;for(i=0;i<count;i++){char cc[10];sscanf(c[i],"%[0-9]",cc);sscanf(cc,"%d",&d);if(strlen(c[i])==strlen(cc)+1){if(c[i][strlen(cc)]=='N') n+=d;if(c[i][strlen(cc)]=='S') s+=d;if(c[i][strlen(cc)]=='E') e+=d;if(c[i][strlen(cc)]=='W') w+=d;}if(strlen(c[i])==strlen(cc)+2){if(c[i][strlen(cc)]=='N'&&c[i][strlen(cc)+1]=='W')nw+=d;if(c[i][strlen(cc)]=='N'&&c[i][strlen(cc)+1]=='E') ne+=d;if(c[i][strlen(cc)]=='S'&&c[i][strlen(cc)+1]=='W') sw+=d;if(c[i][strlen(cc)]=='S'&&c[i][strlen(cc)+1]=='E') se+=d;}}double x=e-w+((ne+se-nw-sw)*sqrt(2))/2;double y=n-s+((nw+ne-sw-se)*sqrt(2))/2;double ss=sqrt(x*x+y*y);count1++;printf("Map #%d\n",count1);printf("The treasure is located at (%.3lf,%.3lf).\n",x,y);printf("The distance to the treasure is %.3lf.\n",ss);printf("\n");}}1505#include<stdio.h>#include<string.h>#include<stdlib.h>int a[510],s[510],t[505][505],num[505],flag[505];int ma(int x,int y){if(x<y) return y;return x;}int main(){int ca;scanf("%d",&ca);while(ca--){int n,m,i,j,k,res;scanf("%d%d",&n,&m);for(i=1;i<=n;i++)scanf("%d",&a[i]);s[0]=0;for(i=1;i<=n;i++)s[i]=s[i-1]+a[i];for(i=1;i<n;i++)t[1][i]=s[i];memset(flag,0,sizeof(flag));for(i=2;i<m;i++)for(j=i;j<n;j++){res=1000000000;for(k=i-1;k<=j-1;k++)if(res>ma(t[i-1][k],s[j]-s[k])) res=ma(t[i-1][k],s[j]-s[k]);t[i][j]=res;}res=s[n];for(i=m-1;i<n;i++)if(ma(t[m-1][i],s[n]-s[i])<res) res=ma(t[m-1][i],s[n]-s[i]);num[0]=n;for(i=1;i<m;i++){int ti=0;for(j=num[i-1];j>m-i;j--){ti=ti+a[j];if(ti>res) break;}num[i]=j;flag[j]=1;}for(i=1;i<n;i++){if(flag[i]==0) printf("%d ",a[i]);else printf("%d / ",a[i]);}printf("%d\n",a[i]);}}1511#include<iostream>#include<cstring>#include<cstdio>#include<queue>#define inf 2000000000using namespace std;int ct,pre[1000005],len[1000005],v[1000005],h[1000005],n,m,vis[1000005],l[1000005]; int a[1000005],b[1000005],c[1000005];queue<int> Q;void add(int a,int b,int c){pre[ct]=h[a];len[ct]=c;v[ct]=b;h[a]=ct++;}void spfa(){int i;memset(vis,0,sizeof(vis));Q.push(1);vis[1]=1;for(i=1;i<=n;i++)l[i]=inf;l[1]=0;while(!Q.empty()){int t=Q.front();for(i=h[t];i!=-1;i=pre[i])if(l[t]+len[i]<l[v[i]]){l[v[i]]=l[t]+len[i];if(vis[v[i]]==0){vis[v[i]]=1;Q.push(v[i]);}}Q.pop();vis[t]=0;}}int main(){int ca;scanf("%d",&ca);while(ca--){scanf("%d%d",&n,&m);int i,j;__int64 res=0;ct=0;memset(h,-1,sizeof(h));for(i=0;i<m;i++){scanf("%d%d%d",&a[i],&b[i],&c[i]);add(a[i],b[i],c[i]);}spfa();for(i=2;i<=n;i++)res=res+l[i];ct=0;memset(h,-1,sizeof(h));for(i=0;i<m;i++)add(b[i],a[i],c[i]);spfa();for(i=2;i<=n;i++)res=res+l[i];printf("%I64d\n",res);}}1609#include<stdio.h>#include<stdlib.h>int a[105][105];int main(){int n;while(scanf("%d",&n)!=EOF){if(n==0){printf("*\n");break;}int i,j;for(i=0;i<101;i++)for(j=0;j<101;j++)a[i][j]=0;for(i=0;i<n;i++){int m,k;scanf("%d%d",&m,&k);a[m][k]=a[m][k]+1;}for(i=1;i<101;i++)for(j=1;j<101;j++)if(i*j!=1){if(a[i][j-1]>=a[i-1][j])a[i][j]=a[i][j]+a[i][j-1];elsea[i][j]=a[i][j]+a[i-1][j];}printf("%d\n",a[100][100]);}}1611#include<iostream>using namespace std;int f[30005],cont[30005];int findf(int a){if(f[a]!=a) f[a]=findf(f[a]);return f[a];}void com(int a,int b){int x=findf(a);int y=findf(b);if(x==y) return;if(cont[x]<=cont[y]){f[x]=y;cont[y]=cont[x]+cont[y];}else{f[y]=x;cont[x]=cont[x]+cont[y];}}int main(){int m,n;while(scanf("%d%d",&n,&m)!=EOF&&n){int num,st,i,j,ed;for(i=0;i<n;i++){f[i]=i;cont[i]=1;}for(i=0;i<m;i++){scanf("%d%d",&num,&st);for(j=1;j<num;j++){scanf("%d",&ed);com(st,ed);}}printf("%d\n",cont[findf(0)]);}}1651#include<stdio.h>#include<stdlib.h>long a[105],i,s[105][105],j,t,k;int main(){int n;while(scanf("%d",&n)!=EOF){for(i=0;i<n;i++)scanf("%ld",&a[i]);for(i=0;i<n-1;i++)s[i][i+1]=0;for(j=2;j<n;j++)for(i=0;i+j<n;i++){t=100000000;for(k=i+1;k<i+j;k++)if(s[i][k]+s[k][i+j]+a[i]*a[k]*a[i+j]<t)t=s[i][k]+s[k][i+j]+a[i]*a[k]*a[i+j];s[i][i+j]=t;}printf("%ld\n",s[0][n-1]);}}1753#include<iostream>using namespace std;int t[]={19,39,78,140,305,626,1252,2248,4880,10016,20032,35968,12544,29184,58368,51200}; #define SIZE 65535int BFS(int state){int visited[SIZE],d[SIZE],u,v,i;int Qu[SIZE],rear,front;memset(visited,0,sizeof(visited));visited[state]=1;d[state]=0;rear=front=0;Qu[++rear]=state;while(rear!=front){u=Qu[++front];for(i=0;i<16;++i) {v=u^t[i];if(v==0 || v==65535) return d[u]+1;if(visited[v]==0){visited[v]=1;d[v]=d[u]+1;Qu[++rear]=v;}visited[u]=-1;}return -1;}int main(){char ch[5][5];int i,j,start;start=0;for(i=0;i<4;++i)scanf("%s",ch[i]);for(i=0;i<4;++i)for(j=0;j<4;++j)if(ch[i][j]=='b') start^=(1<<((3-i)*4+(3-j)));if(start==0||start==65535) printf("0\n");else{int result=BFS(start);if(result==-1) printf("Impossible\n");else printf("%d\n",result);}}1797#include<stdio.h>#include<string.h>int a[1005][1005],vis[1005],len[1005];int mm(int a,int b){return a<b?a:b;}int main(){int ca,ct=0;scanf("%d",&ca);while(ca--){int n,m;scanf("%d%d",&n,&m);int i,j;memset(a,0,sizeof(a));for(i=1;i<=m;i++)int r,t,l;scanf("%d%d%d",&r,&t,&l);a[r][t]=l;a[t][r]=l;}memset(vis,0,sizeof(vis));for(i=2;i<=n;i++)len[i]=a[1][i];vis[1]=1;for(i=1;i<n;i++){int mmax=0,k;for(j=2;j<=n;j++)if(vis[j]==0&&len[j]>mmax){mmax=len[j];k=j;}vis[k]=1;if(k==n) break;for(j=2;j<=n;j++)if(vis[j]==0){int length=mm(len[k],a[k][j]);if(length>len[j]) len[j]=length;}}printf("Scenario #%d:\n%d\n\n",++ct,len[n]);}}1845#include<iostream>#include<cstring>using namespace std;#define mod 9901__int64 pri[7505],a[100],num[100];void prime(){memset(pri,0,sizeof(pri));int i,j;for(i=2;i<=90;i++)for(j=2;i*j<=7500;j++)j=0;for(i=2;i<=7500;i++)if(pri[i]==0) pri[j++]=i;}__int64 yu(__int64 a,__int64 b){__int64 res=1,c=mod;while(b){if(b%2==0){a=(a%c)*(a%c)%c;b=b/2;}else{res=res*a%c;b--;}}return res;}__int64 f(__int64 a,__int64 b){if(b==0) return 1;if(b==1) return (1+a)%mod;if(b%2==0) return (yu(a,b/2)+(1+yu(a,b/2+1))*f(a,b/2-1))%mod;return ((1+yu(a,b/2+1))*f(a,b/2))%mod;}int main(){prime();int n,m;while(scanf("%d%d",&n,&m)!=EOF){int i,j=0;if(n==0){printf("1\n");continue;}for(i=0;pri[i]*pri[i]<=n;i++)if(n%pri[i]==0){int t=0;while(n%pri[i]==0){t++;n=n/pri[i];}a[j]=pri[i];num[j++]=t;}if(n!=1){a[j]=n;num[j++]=1;}__int64 res=1;for(i=0;i<j;i++)res=res*f(a[i],num[i]*m)%mod;printf("%I64d\n",res);}}1941#include<stdio.h>#include<string.h>int h[22],s[22];char c[1025][2050],ss[1025][2050];void solve(int m){int i,j;if(m==1){h[m]=4;s[m]=2;c[1][1]=' ';c[1][4]=' ';c[1][2]='/';c[1][3]='\\';c[2][1]='/';c[2][2]='_';c[2][3]='_';c[2][4]='\\';memcpy(ss,c,sizeof(c));}if(m!=1){memset(c,' ',sizeof(c));solve(m-1);h[m]=h[m-1]*2;s[m]=s[m-1]*2;for(i=s[m-1]+1;i<=s[m];i++)for(j=1;j<=h[m-1];j++)c[i][j]=c[i][j+h[m-1]]=ss[i-s[m-1]][j];for(i=1;i<=s[m-1];i++)for(j=h[m-1]/2*3;j>h[m-1]/2;j--){c[i][j]=ss[i][j-h[m-1]/2];c[i][j-h[m-1]/2]=' ';}memcpy(ss,c,sizeof(c));}}int main(){int n,i,j,k;h[0]=2;solve(10);while(scanf("%d",&n)!=EOF&&n){for(i=1;i<=s[n];i++){for(j=h[9]-h[n]/2+1;j<=h[9]+i;j++)printf("%c",c[i][j]);printf("\n");}printf("\n");}}1947#include<iostream>#include<algorithm>using namespace std;#define big 10000000int num[155],flag[155],son[155][155],step[155][155],n,m,root; void dsf(int v)int i,j,k;if(v!=root) step[v][1]=num[v]+1;else step[v][1]=num[v];for(i=0;i<num[v];i++){dsf(son[v][i]);for(j=m-1;j>=1;j--)if(step[v][j]<big){for(k=1;k+j<=m;k++)step[v][k+j]=min(step[v][k+j],step[v][j]+step[son[v][i]][k]-2);}}}int main(){while(scanf("%d%d",&n,&m)!=EOF){memset(num,0,sizeof(num));memset(flag,0,sizeof(flag));int i,a,b,j;for(i=1;i<n;i++){scanf("%d%d",&a,&b);flag[b]=1;son[a][num[a]++]=b;}for(i=1;i<=150;i++)for(j=1;j<=150;j++)step[i][j]=big;for(i=1;i<=n;i++)if(flag[i]==0){root=i;dsf(i);break;}int res=big;for(i=1;i<=n;i++)if(step[i][m]<res) res=step[i][m];printf("%d\n",res);}}1964#include<stdio.h>#include<string.h>char s[1005][1005][2];int a[1005][1005],pre[1005],next[1005];int main(){int ca;scanf("%d",&ca);while(ca--){int n,m,i,j,k,res=0;scanf("%d%d",&n,&m);for(i=0;i<n;i++)for(j=0;j<m;j++)scanf("%s",s[i][j]);for(i=0;i<m;i++)if(strcmp(s[0][i],"F")==0) a[0][i]=1;else a[0][i]=0;for(i=1;i<n;i++)for(j=0;j<m;j++)if(strcmp(s[i][j],"F")==0) a[i][j]=a[i-1][j]+1;else a[i][j]=0;for(i=0;i<n;i++){memset(pre,-1,sizeof(pre));for(j=1;j<m;j++)for(k=j-1;k!=-1;k=pre[k])if(a[i][k]<a[i][j]){pre[j]=k;break;}for(j=0;j<m;j++)next[j]=m;for(j=m-2;j>=0;j--)for(k=j+1;k!=m;k=next[k])if(a[i][k]<a[i][j]){next[j]=k;break;}for(j=0;j<m;j++)if((next[j]-pre[j]-1)*a[i][j]>res) res=(next[j]-pre[j]-1)*a[i][j];}printf("%d\n",res*3);}}。
ACM第05讲动态规划精品PPT课件
printf("%d", MaxSum(1, 1)); }
11.10.2020
15
1)既然问题出在重复计算,那么解决的办法,当然就是,一个值一 旦算出来,就要记住,以后不必重新计算。
{ if (n <= 1) return 1; return fibonacci(n-1) + fibonacci(n-2);
}
11.10.2020
5
存在的问题:
递归将原问题分成很多子问题 但是,有大量的子问题被重复计算
如何解决?
11.10.2020
6
用动态规划解题
首先要把原问题分解为若干个子问题,这一点 和前面的递归方法类似。
ACM暑期集训
动态规划法
第五讲
动态规划(1)
(Dynamic programming)
11.10.2020
2
动态规划法:重在公式推导,程序极其简练
递归->动态规划( Dynamic programming,简 称DP)
ACM动规高手:动规小王子
11.10.2020
3
引例 Fibonacci数列
如数字2,只要选择它下面较大值的结点19前进就可 以了。所以实际求解时,可从底层开始,层层递进,最后 得到最大值。
结论:自顶向下的分析,自底向上的计算。
11.10.2020
13
递归分析
7 38 8 10 2744 45265
7 38 8 10 2744 45265
以D( r, j)表示第r 行第 j 个数字(r,j 都从1 开始算), 以MaxSum(r, j) 代表从第 r 行的第 j 个数字到底边的 最佳路径的数字之和,则本题是要求 MaxSum(1, 1) 。
acm 二分查找题型
acm二分查找题型
在ACM竞赛中,二分查找是一种常见且重要的算法,用于在有序数组或有序数据集中查找特定元素。
以下是一些常见的ACM二分查找题型及解题思路:
1.普通二分查找:
-题型描述:在有序数组中查找某个特定元素的位置。
-解题思路:通过比较中间元素与目标元素的大小关系,不断缩小查找范围,直到找到目标元素或确认不存在。
2.查找第一个等于目标值的元素:
-题型描述:在有序数组中找到第一个等于给定值的元素。
-解题思路:在普通二分查找基础上,当找到目标值时,继续向左搜索,直到找到第一个等于目标值的元素。
3.查找最后一个等于目标值的元素:
-题型描述:在有序数组中找到最后一个等于给定值的元素。
-解题思路:在普通二分查找基础上,当找到目标值时,继续向右搜索,直到找到最后一个等于目标值的元素。
4.查找第一个大于等于目标值的元素:
-题型描述:在有序数组中找到第一个大于等于给定值的元素。
-解题思路:在普通二分查找基础上,当找到目标值时,继续向左搜索,直到找到第一个大于等于目标值的元素。
5.查找最后一个小于等于目标值的元素:
-题型描述:在有序数组中找到最后一个小于等于给定值的元素。
-解题思路:在普通二分查找基础上,当找到目标值时,继续向右搜索,直到找到最后一个小于等于目标值的元素。
这些题型是二分查找在ACM竞赛中常见的应用场景。
在解题时,需要根据具体问题要求调整二分查找的边界条件和终止条件,以确保得到正确的答案。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(2)中根遍历
对树的访问次序是:
1.先访问左子树 2.再访问根结点 3.最后访问右子树 4.对于左右子树的访问也要满足以上规则
示例如下:
2020/12/10
24
1
2
3
4
56
7
以上二叉树的中根遍历序列是:??
4、 2、 5、 1、 6、 3、 7
2020/12/10
分别有什么特点呢?
2020/12/10
21
(1)先根遍历
对树的访问次序是:
1.先访问根结点 2.再访问左子树 3.最后访问右子树 4.对于左右子树的访问也要满足以上规则
示例如下:
2020/12/10
22
1
2
3
4
56
7
以上二叉树的先根遍历序列是:??
1、2、4、5、3、6、7
2020/12/10
23
3.按上述思想流程应为
a.从1—100000中搜出质数 b.两层循环,试遍所有的组合(p,q可能相等) c.每种组合去判断是否符合条件,如是,将 p*q与当前最大值比较,判断,保存
2020/12/10
16
面临的问题:
超时!
从1—100000的质数运算约为1e+8,而这 只是准备工作。
因此,如不加以分析简化此题无法在规 定时间内出解
同时,要求: p*q<=m<=100000
所以无论如何质数都不能超过10000。(事实上,
不会超过9091)
2020/12/10
18
搜索时的技巧:
搜索顺序很重要。建议从大往小搜 ( num:质数的个数 ) for (i=num-1;i>=0;i--) for (j=i;j<=num-1;j++) ……
题目链接
Again
Sample Input
512 99999 999 999 1680 5 16 1970 1 1 2002 4 11 000
Sample Output 22 313 313 23 73 43 43 37 53
2020/12/10
14
获取有用信息
a.给定整数m,a,b(4 < m <= 100000 and 1 <= a <= b <= 1000)
b.需要找到两个数(不妨设为p,q)满足以下 条件:
p,q均为质数;
p*q<=m;
a/b <= p/q <= 1;
c.输出所有满足以上条件的p,q中乘积最大 的一对p,q
2020/12/10
15Βιβλιοθήκη 算法分析1.典型的搜索 从所有可能的p,q中寻找满足条件的一对
2.p,q的要求 p,q均为质数,且p<=q<=100000;
11
说明:
本题除了可以练习基本搜索算法,也是 练习字符串处理的好题目,题中用到的 相关知识点有:
求反串 求子串 字符串查找 求字符串长度
强烈推荐!!
2020/12/10
12
再来一道数值型搜索题
2020/12/10
13
HDOJ_1239
Calling Extraterrestrial Intelligence
第五讲 搜索题
2020/12/10
1
统计信息:
根据“信息学初学者之家”网站的统计,
Ural(俄罗斯的Ural州立大学的简称 ,那里设立 了一个Ural Online Problem Set,并且支持 Online Judge。 )的题目类型大概呈如下的分布 :
搜索 动态规划 贪心 构造 图论
约10% 约15% 约5% 约5% 约10%
——摘自《ACM竞赛之新人向导 》
2020/12/10
4
什么是搜索算法呢?
搜索算法是利用计算机的高性能来有目 的地穷举一个问题的部分或所有的可能情况 ,从而求出问题的解的一种方法。
搜索过程实际上是根据初始条件和扩展 规则构造一棵解答树并寻找符合目标状态的 节点的过程。
2020/12/10
5
预热一下:二分查找
2 3 4 5 6 8 12 20 32 45 65 74 86 95 100
head
mid
tail
2020/12/10
6
查找示意图:
A[1]~A[15]
A[1]~A[7]
A[9]~A[15]
A[1]~A[3] A[5]~A[7] A[1]~A[1] A[3]~A[3]
……
2020/12/10
7
思考:
计算几何 纯数学问题 数据结构 其它
约5%
约20%
约5% 约25%
2020/12/10
2
搜索题特点分析:
题意容易理解 算法相对固定 编程有路可循 竞赛必备知识
2020/12/10
3
引言
“算法中最基本和常用的是搜索,主要是回溯和
分支限界法的使用。这里要说的是,有些初学者 在学习这些搜索基本算法是不太注意剪枝,这是 十分不可取的,因为所有搜索的题目给你的测试 用例都不会有很大的规模,你往往察觉不出程序 运行的时间问题,但是真正的测试数据一定能过 滤出那些没有剪枝的算法。实际上参赛选手基本 上都会使用常用的搜索算法,题目的区分度往往 就是建立在诸如剪枝之类的优化上了。 ”
1、在一百万个元素里查找某个元素 大约需要比较多少次?
2、时间复杂度:O(logN)
2020/12/10
8
举例分析
从简单的字符串搜索讲起
2020/12/10
9
HDOJ_1238 Substrings
题目链接
Sample Input 2 3 ABCD BCDFF BRCD 2 rose orchid
Sample Output 2 2
2020/12/10
10
题目分析:
这是一道入门级别的搜索题,基本思想
比较简单,但是如果用最朴素的算法,
可能会超时如何降低算法的复杂度呢?
下面的算法如何:
先将字符串按长度从短到长排序,枚举 最短的字符串的子串,判断是否都是别 的字符串的子串,求出最大长度即可。
2020/12/10
2020/12/10
17
深入分析
p,q的范围其实可在2—50000(why?) 然而,这是最小的范围吗?
考虑大于10000的某个质数,不妨设为Q,另一 个质数为P,则:
如果P<10,P/Q<0.001 如果P>10,P*Q>100000
而考虑到a,b的取值范围(1<=a<=b<=1000) 可知min(a/b)=0.001
注意剪枝:
If ( a[j]>m || a[j]*a[i]>m || ( (double)a[i]/a[j])<s )
……
2020/12/10
19
真正的搜索题
迷宫搜索
2020/12/10
20
预备知识——树的遍历
树的遍历主要有如下四种方法:
1.先根/序遍历 2.中根/序遍历 3.后根/序遍历 4.层次遍历