问题 B: 【分治】Babelfish
题目:
You have just moved from Waterloo to a big city. The people here speak an incomprehensible dialect of a foreign language. Fortunately, you have a dictionary to help you understand them.
输入
Input consists of up to 100,000 dictionary entries, followed by a blank line, followed by a message of up to 100,000 words. Each dictionary entry is a line containing an English word, followed by a space and a foreign language word. No foreign word appears more than once in the dictionary. The message is a sequence of words in the foreign language, one word on each line. Each word in the input is a sequence of at most 10 lowercase letters.
输出
Output is the message translated to English, one word per line. Foreign words not in the dictionary should be translated as “eh”.
代码:
#include <iostream>
#include <map>
#include <cstdio>
using namespace std;
map<string,string>m;///即使是string到string的映射,char[]型的也可以使用
int main()
{
char from[100],to[100],ori[100],target[100];
while(cin.getline(ori,100)&&ori[0]!='\0')///ori[0]是不等于\0不是\n
{
sscanf(ori,"%s %s",to,from);///注意sscanf的用法
m[from]=to;///char[]到char[]的映射
}
while(~scanf("%s",target))
{
if(m.find(target)!=m.end())
cout<<m[target]<<'\n';
else
cout<<"eh"<<'\n';
}
}
问题 C: 【分治】魔法石的诱惑
题目:
修罗王远远地看见邪狼狂奔而来,问道:“慌慌张张地跑什么?” 邪狼大口大口地喘气:“我路过一家魔法石店,看到摆着那么多高阶魔法石,我就跑进去抢了一大袋。” 修罗王怒道:“光天化日,朗朗乾坤,众目睽睽之下,你也敢抢?” 邪狼:“我抢魔法石的时候,压根儿就没看见人,眼里只看见魔法石了。” 修罗王:“……” 其实邪狼的贪婪很容易理解,因为高阶魔法石有一个特征,即它的重量进行阶乘运算后末尾有几个0,就拥有同等重量普通魔法石几倍的魔法力。例如5!=5×4×3×2×1=120,而120结尾包含1个零,这意味着该魔法石拥有同等重量的普通的魔法石1倍的魔法力。你的任务是找到最小自然数N,使N!在十进制下包含Q个零。
输入
一个数Q(0≤Q≤108)
输出
如果无解,输出“No solution”,否则输出N。
代码:
#include <iostream>
#include <map>
#include <cstdio>
using namespace std;
int get0(int x)///获取0的个数
{
int bit=5,cnt=0;
while(bit<=x)
{
cnt+=x/bit;
bit*=5;
}
return cnt;
}
int solve(int x)///二分求解
{
int l=1,r=1e9;
while(r>l)///不可带等号,因为下面有r=mid
{
int mid=(l+r)/2;
if(get0(mid)>x) r=mid-1;
else if(get0(mid)<x) l=mid+1;
else r=mid;///0的个数等于x了,那么使r=mid,在区间[l,mid]中找,因为要求最小的r
///例子:若x=4,r=24,r!也有4个0,但是r不是最小的,20才是
}
return r;
}
int main()
{
int x;cin>>x;
if(x==0)///0!=1
{
cout<<0<<endl;
return 0;
}
int ans=solve(x);
if(get0(ans)!=x) cout<<"No solution"<<endl;///个数不相符,无解
else cout<<ans<<endl;
}
题目:
The FORTH programming language does not support floating-point arithmetic at all. Its author, Chuck Moore, maintains that floating-point calculations are too slow and most of the time can be emulated by integers with proper scaling. For example, to calculate the area of the circle with the radius R he suggests to use formula like R * R * 355 / 113, which is in fact surprisingly accurate. The value of 355 / 113 ≈ 3.141593 is approximating the value of PI with the absolute error of only about 2*10-7. You are to find the best integer approximation of a given floating-point number A within a given integer limit L. That is, to find such two integers N and D (1 <= N, D <= L) that the value of absolute error |A - N / D| is minimal.
输入
The first line of input contains a floating-point number A (0.1 <= A < 10) with the precision of up to 15 decimal digits. The second line contains the integer limit L. (1 <= L <= 100000).
输出
Output file must contain two integers, N and D, separated by space.
思路:
追赶法求解,cmp为输入的目标值,maxn为最大的分子分母的上限,temp=cmp-i/j,Abs为temp的绝对值,minn为Abs的最小值,初始化为1000000000;
1)temp>0时,说明i/j不够大,i++,i/j追赶cmp
2)temp<0时,i/j太大,j++,缩小i/j与cmp的距离
3)Abs>minn时,更新minn,p,q
当i,j其中一个大于maxn时停止;
#include <iostream>
#include <map>
#include <cstdio>
#include <cmath>
using namespace std;
int maxn;
int p,q;
void solve(double cmp)
{
int i=1,j=1;
double minn=10000000;
while(i<=maxn&&j<=maxn)
{
double temp=cmp-i*1.0/j;
double Abs=abs(temp);
if(Abs<minn)
{
minn=Abs;
p=i,q=j;
}
if(temp>0) i++;
else j++;
}
}
int main()
{
double cmp;
cin>>cmp>>maxn;
solve(cmp);
cout<<p<<' '<<q<<endl;
}
问题 E: 【分治】逃亡
题目:
邪狼紧张地说:“老大,警察快追过来了,我们快逃跑吧!”
修罗王傲然道:“在我的字典里没有逃跑。。。”
邪狼内心崇敬地想:“老大实在是太有领袖范了……”
修罗王接着说:“只有战略转移。”
邪狼:“……”
现在,修罗王和邪狼两人需要从A地出发尽快到达B地。出发时A地有一辆可带一人的自动驾驶悬浮车。又知两人步行速度相同。问怎样利用小车才能使两人尽快同时到达B地。
输入
有三个int类型整数,分别表示A、B两地的距离,步行速度和车速。
输出
有一个小数位数为2的浮点数,即最短时间。
思路:
二分第一次车走的距离,如何分别求出两个人到达的时间,当两个近乎相等时,返回时间
#include <iostream>
#include <map>
#include <cstdio>
#include <cmath>
using namespace std;
double solve(double s,double a,double b)
{
double l=0,r=s,t1,t2;
while(l<=r)
{
double mid=(l+r)/2;
t1=mid/b+(s-mid)/a;
t2=mid/b+(mid-mid/b*a)/(a+b)+(s-(mid-mid/b*a)/(a