问题求解与程序设计 第三讲 称重问题 李文新 2004.2 – 2004.6 内容提要 作业总结 - 1008 作业总结 - 1013 何林冬令营报告 – 称球问题 自学及讨论 – 征服者 作业 作业总结 - 1008 题意 • Haab 19个月 前18个月每月20天 第19个月5天 0-19 月名 0-5 月名 • Tzolkin 13个月 天数为20个轮转 1mix 2--- 3--- … 问题 • 将Haab日期转换成Tzolkin日期 源程序 1008 源程序 作业总结 - 1013 题意 • 12枚硬币,其中一枚是假币,可能轻也可能重 • 称三次,每次左右硬币数目相等,结果:轻重平 问题 • 求出假币,并给出其轻重 源程序 • 1013源程序 长沙雅礼中学 何林 一类称球问题的 解法 问题的提出 给定N个球 有个比标准球重的次品混入其中 你有一架天平,用最少的次数找出这个次品。 N 1 = 3 2 3 2 1 ①是次品 1 2 1 2 ②是次品 ③是次品 N=3时称1次就可 以找出次品 1 2 4 NA = 9 3 5 6 B A 次品在A中 A B 次品在B中 A B 次品在C中 7 B 8 9 C • 通过一次称量, 可以把次品可能存 在的范围从9个, 缩小到3个 • N = 3的时候一次 就能称出次品 N = 9时称2次 更一般的情况 N = 3k 1 2 …… k A 1 2 …… k B 1 2 …… k C 更一般的情况 B A 次品在A中 A B A B 次品在B中 次品在C中 范围缩小 到原来的 1/3 更一般的情况 n = 3k+1, n = 3k+2和n=3k类似,也是均分 成三堆 每次称量把范围大致缩小到原来的1/3 因此:从n个球中找次品至多要称[log3n]次。 ([]统一表示取上整) 判定树 [log3n]无疑是可行解。 最优性 为什么三分? 因为天平只有三种可能: 左偏、右偏、平衡 判定树 称(1, 2) > 1 = 3 < 2 叶子代表结果 非叶子代表一次称量 每个非叶子节点都有三个孩子,表示天 平左偏、右偏、平衡 判定树 比较(1,2,3)与(4,5,6) > 比较(1)与(2) > 1 = 3 < = 比较(7)与(8) 比较(4)与(5) > > < 2 7 = 9 < 8 4 判定树的深度就是称量次数 一个有意义的判定树至少n个叶子节点 = 6 < 5 判定树 N个叶子的三叉树的深度h >= [log3n] [log3n]是最优解 小结 引进了有力工具:判定树。将主观的直觉严 谨化。 三分法是解决这类问题的根本着眼点。 三分时必须充分的均匀 Problem Conqueror’s batalion Table of Contents The problem Solution The problem CENTRAL EUROPEAN OLYMPIAD IN INFORMATICS 30 June – 6 July 2002 Day 1: conquer Conqueror’s battalion Time limit: 1 s Memory limit: 16 MB The problem In the whole history of mankind one can find several curious battles, like the following one in France, in 1747. . . The problem There was a fortress in Bassignac-leHaut, a small village lying on the left bank of river Dordogne, just over the Chastang dam. From the dam up to the fortress there was a wide staircase made out of red marble. The problem One day in the morning, the guard spotted a large battalion Approaching the fortress, with a dreaded leader – The Conqueror. The problem When The Conqueror reached the fortress, he was already awaited by its commandant. The commandant proposed: “I see that you have many soldiers behind you, standing on the stairs. We can play a small ‘game’: The problem In each round, you will divide your soldiers into two groups in an arbitrary way. Then I will decide which one of them stays and which one goes home. Each soldier that stays will then move up one stair. The problem If at least one of your soldiers reaches the uppermost stair, you will be the winner, in the other case, you will be the loser. The problem The Conqueror immediately liked this game, so he agreed and started to ‘conquer’. The problem Task Your role is The Conqueror’s now. There are N stairs to the fortress (2 <= N <= 2000) and you have at most 1 000 000 000 soldiers. The problem For each stair, you are given the number of soldiers standing on it, with number 1 being the uppermost stair and N the bottom one. None of your soldiers stands on stair 1 at the beginning. The problem For each starting position given to your program, if the position is winning (i.e. there is a strategy that enables you to win the game regardless of your opponent’s moves), Your program should win. Otherwise it should just play the game (and lose) correctly. The problem This is an interactive problem; you will play against a library as specified below. In each round, your program will describe a group of soldiers to our library. The library returns 1 or 2 specifying which group of soldiers should stay (1 means the group you described, 2 means the rest of the soldiers). The problem In case the game ends (either because you won or there are no more soldiers in the game), the library will terminate your program correctly. Your program may not terminate in any other way. The problem Library interface The library libconq provides two routines: • start – returns the number N and fills an array stairs with numbers of soldiers standing on the stairs (i.e. there are stairs[i] soldiers standing on stair i) The problem • step – takes an array subset (with at least N1 elements), describing the group of soldiers you chose, and returns 1 or 2 as described above; the group of soldiers is specified by numbers of soldiers on each stair, as in the start function The problem If you fail to specify a valid group of soldiers, the game will be terminated and your program will score zero points for the particular test case. Please note that also in C/C++ the stairs are numbered starting from 1. The problem Following are the declarations of these routines in FreePascal and C/C++: procedure start(var N: longint; var stairs:array of longint); function step(subset:array of longint): longint; void start(int *N, int *stairs); int step(int *subset); The problem Below you can find examples of library usage in both FreePascal and C/C++; both fragments do the same – start the game and then play one round, with the chosen group containing all soldiers on randomly chosen stairs. Your real program will probably play the rounds in an infinite loop. The problem You are strongly encouraged to define the arrays stairs and subset in the same way as they are defined in the example below. The problem FreePascal example: uses libconq; var stairs: array[1..2000] of longint; subset: array[1..2000] of longint; i,N,result: longint; ... start(N,stairs); ... ... for i:=1 to N do if random(2)=0 then subset[i]:=0 else subset[i]:=stairs[i]; result:=step(subset); ... The problem C/C++ example: #include "libconq.h" int stairs[2001]; int subset[2001]; int i,N,result; ... start(&N, stairs); ... for (i=1;i<=N;i++) if (rand()%2==0) subset[i]=0; else subset[i]=stairs[i]; result=step(subset); ... The problem You have to link the library to your program – by uses libconq; in FreePascal and by #include "libconq.h“ in C/C++, where you have to compile your program by adding libconq.c to the compiler arguments. The problem An example of the game You: Library: start(N,stairs) N=8, stairs=(0,1,1,0,3,3,4,0) step((0,1,0,0,1,0,1,0)) returns 2(0,0,1,0,2,3,3,0,0) step((0,1,0,0,0,1,0,0)) returns 2(0,0,0,2,3,2,0,0,0) step((0,0,0,3,2,0,0,0)) returns 1(0,0,0,3,2,0,0,0,0) step((0,0,2,0,0,0,0,0)) returns 2(0,0,1,2,0,0,0,0,0) step((0,1,0,0,0,0,0,0)) returns 2(0,0,2,0,0,0,0,0,0) step((0,1,0,0,0,0,0,0)) no return: you won The problem The file libconq.dat for the example above would look like this: 8 01103340 Solution Let’s try to tell somehow how good a position is. If we have two soldiers on the same stair (and no other soldiers), in the next round we will have at most only one soldier but one stair higher. In this way, one soldier on the stair S is equivalent to two soldiers on the stairs S+1. Solution From now on a soldier on the stair S will have the value 2N-S. The value of a position will be the sum of the values of all the soldiers. Note that all positions, where the Conqueror has won, have the value at least 2N-1 because there is a soldier on the stair number 1. Solution 25-1 1 2*25-2 2 1 4 2 A soldier on stair S has value 2N-S 4*25-3 8*25-4 8 3 16 4 5 16*25-5 Solution n1*25-2 n1 1 n2 2 n2*25-3 n3 3 4 5 A position’s value = sum (all soldiers) n3*25-4 Solution Losing positions If the value of the position is less than 2N1 and the commandant plays optimally, the Conqueror will lose. Solution Proof If the value is less than 2N-1 , the Conqueror didn’t win yet. Let’s take a look at one round of the game. The Conqueror divides his soldiers in some way. The commandant will choose this group to stay and the other to leave. Solution When any soldier moves up one stair, his value doubles. Therefore the value of the new position will be less than 2*2N2=2N-1 and the number of the soldier will decrease. There is a finite number of soldiers, and so the game ends in a finite number of moves. The value of a position will always be less than 2N-1, also at the end there will be no soldiers and the Conqueror will lose. Solution Losing position smaller <2N-1 larger <2*2N-2=2N-1 …………………………….. Solution Winning position If the value of the position is at least than 2N-1 and the Conqueror plays optimally, he will win. Solution Proof The Conqueror has to divide the soldiers into two groups so that the value of each group will be at least 2N-2. Then regardless of the commandant’s choice the new position will again have the value at least 2N-1. and there will be less soldiers than before. Solution There is a finite number of soldiers, and so the game will end in a finite number of moves. At the end of the game the value of the position will be at least 2N-1. This means that some of the soldiers has to stand on the stair 1 and the Conqueror won. We only need to show, that the Conqueror can always divide the soldiers in the way described above. Solution Lemma: Let a1,…aM(2N-2 >=a1>=…>=aM, M>=2) be powers of two with sum(ai,1<=i<=M) >= 2N-2. Then for some K holds sum(ai,1<=i<=k) = 2N-2. Solution Example 24>=23>= 23>= 22>=22 (M=4, N=6) 23 + 23 + 22 +22 > 24 Then K=2, 23 + 23 = 24 Solution Proof Induction on M. For M=2 the lemma holds. 2N-2 >= a1 >= a2 a1 + a2 >= 2N-2 Either a1= 2N-2(k=1) or (a1 = a2 = 2N-3 and a1 + a2 = 2N-2(k=2) Solution Now let M>2 and sum(ai,1<=i<=M) > 2N-2 Because ais are multiple of 2, sum(ai,1<=i<=M) = k1aM 2N-2 = k2aM Therefore sum(ai,1<=i<=M) >= 2N-2+aM Then sum(ai,1<=i<=M-1) >=2N-2 We may apply the induction assumption. Solution From the lemma we get that if the sum of the soldiers’ values is at least 2N-1, we may select the first (eg. Closet to the top of the staircase) few of them so that the sum of their values will be exactly 2N-2 . The Conqueror may also divide his soldiers into these two groups. Solution 3 2N-3 4 2N-4 4 2N-4 5 2N-5 …… …… 2N-2 Solution If we are in a losing position, we choose an empty set and loose instantly. If we are in a winning position, we find the place where to split the soldiers by adding the values of soldiers on stairs 1,2,…until the value reaches 2N-2. 本节课小结 作业总结 - 1008 作业总结 - 1013 何林冬令营报告 – 称球问题 自学及讨论 – 征服者 作业 作业 1016 1048
© Copyright 2026 Paperzz