您的位置:首页 > 运维架构

USACO 2015 US OPEN BRONZE 铜组 题解

2016-02-15 19:35 337 查看
USACO
2015USOPENBRONZE

好吧,我没什么时间了,我就干脆把标程放上去,接着解释一下就行了。

PROBLEM
1MOOCRYPTION


众所不知的,奶牛们很喜欢玩智力游戏。John农夫最近发明了一个有趣的“找单词”游戏。
这个游戏的例子如下:

USOPEN
OOMABO
MOOMXO
PQMROM


作为奶牛,他们只对单词“MOO”有兴趣,这个可能会出现在找单词游戏中的任何地方,可能是水平的,可能是垂直的,也有可能是对角线的出现。上面的例子出现了6个MOO。

John农夫也是单词游戏的粉丝。
由于奶牛们不想在他们有机会试一下之前,John就把解开了,他们把游戏的内容用一个代替密码给加密了。这个代替密码将字母表里的每个字母用另外一个字母代替了。比如说,A可能对应着X,B可能对应着A等等。没有哪个字母和自己对应,没有两个字母对应到同样一个字母上(否则解码时会引起歧义)。

不幸的是,这群傻奶牛不记得用来解码的代替密码了。所以求求你帮他们找到一个合适的代替密码,使这个游戏中出现MOO的次数最多。

输入格式(moocrypt.in):

第一行包括N和M,分别表示这个游戏的行与列(每个最多50)。接下来的N行,每行包括M个字符,来表示这个游戏的一行。每个字符都是从A-Z之间的一个大写字母。

输出格式(moocrypt.out):

输出当游戏用合适的代替密码解码后可以出现的最多MOO的次数

输入样例:

46

TAMHGI

MMQVWM

QMMQSM

HBQUMQ

输出样例:

6

这个就是题目描述中的加密后的游戏。这里M和O分别用Q和M代替了。

【题目描述】
这一道题写一个广搜就好了,但但要注意队列的长度最好要开大一点,直接搜索行与列就可以了。
【代码】

#include<iostream>
#include<vector>
#include<algorithm>
#include<cstdio>

usingnamespacestd;

intN,M;
vector<string>A;

intdr[]={-1,-1,-1,0,1,1,1,0};
intdc[]={-1,0,1,1,1,0,-1,-1};

charget(intr,intc){
if(r<0||N<=r||c<0||M<=c){
//weareoutsidethegrid,returnanon-letter
return'_';
}
returnA[r][c];
}

intmain(){
freopen("moocrypt.in","r",stdin);
freopen("moocrypt.out","w",stdout);

cin>>N>>M;
A.resize(N);
for(inti=0;i<M;i++){
cin>>A[i];
}

intbest=0;
for(charmch='A';mch<='Z';mch++){
//pickacharacterthatwillbesettoM
if(mch=='M'){
continue;
}
for(charoch='A';och<='Z';och++){
//pickacharacterthatwillbesettoO
if(och=='O'||mch==och){
continue;
}
intresult=0;
for(inti=0;i<N;i++){
for(intj=0;j<M;j++){
//checkthefirstcharacterwouldbeM
if(get(i,j)!=mch){
continue;
}
//tryallpossiblewordsstartingatsquare(i,j)
for(intk=0;k<8;k++){
//checkthenexttwocharacterswouldbeO
if(get(i+1*dr[k],j+1*dc[k])==och&&
get(i+2*dr[k],j+2*dc[k])==och){
result++;
}
}
}
}
best=max(best,result);
}
}
cout<<best<<endl;

return0;
}


PROBLEM
2BESSIEGETSEVEN


FJ和奶牛Bessie最爱闲时交换数学智力游戏。最近一次FJ给Bessie的数学难倒了可怜的Bessie。
现在她想为FJ给他那么难的题目而复仇。

Bessie给了FJ一个表达式,(B+I)(G+O+E+S)(M),包括七个变量,B,E,S,I,G,O,M(其中O是变量不是数字0)。对每个变量,她给了FJ一个那个变量可能被赋有最多有20个整数值的清单。她问FJ总共有多少种不同的方式来给每个变量赋值使得表达式的最终结果为偶数。

输入格式:(geteven.in

第一行包括一个整数N,接下来的N行,每行包括一个变量以及这个变量可能的值。 每个变量会至少出现一次,最多出现20次。同一个的变量不会被列两次相同的值。每个值都会在-300到300之间。

输出格式:(geteven.out

输出一个整数,表示所有FJ可以给这些变量赋值使得表达式最终的结果是偶数的可能数。

输入样例:

10
B2
E5
S7
I10
O16
M19
B3
G1
I9
M2


输出样例:

6

共有6种变脸赋值的方法:

(B,E,S,I,G,O,M)=(2,5,7,10,1,16,19)->53,244
=(2,5,7,10,1,16,2)->35,496
=(2,5,7,9,1,16,2)->34,510
=(3,5,7,10,1,16,2)->36,482
=(3,5,7,9,1,16,19)->53,244
=(3,5,7,9,1,16,2)->35,496


注意(2,5,7,10,1,16,19)和(3,5,7,9,1,16,19)算两种不同的赋值方法,尽管他们得出的结果是相同的。

【题目分析】 这一道题有很多的方法,比如杨天诚在课上所提出的数学方法。但是最简单的方法应该是直接枚举了。将每个变量所可能的奇偶情况的各自数目存入数组中,接着枚举每个变量的奇偶即可。为什么可以这样呢?因为注意到在这里只需求方案数,而且其只用求所有偶数的可能性,用一下乘法原理,乘一乘就好了。【代码】
#include<iostream>
#include<cstdio>

usingnamespacestd;

intnum[256][2];

boolis_even(intx){
returnx%2==0;
}

intmain(){
freopen("geteven.in","r",stdin);
freopen("geteven.out","w",stdout);

intN;
cin>>N;

for(inti=0;i<N;i++){
charletter;
intval;
cin>>letter>>val;

if(is_even(val)){
num[letter][0]++;
}else{
num[letter][1]++;
}
}

intresult=0;

/*Tryeverypossiblewaythatthevariablescouldbeevenorodd.*/
for(intB=0;B<2;B++)
for(intE=0;E<2;E++)
for(intS=0;S<2;S++)
for(intI=0;I<2;I++)
for(intG=0;G<2;G++)
for(intO=0;O<2;O++)
for(intM=0;M<2;M++){
if(is_even((B+E+S+S+I+E)*(G+O+E+S)*(M+O+O))){
/*Iftheexpressioniseventhenaddthenumberofvariableassignments
*thathavethevariablesodd/even.
*/
result+=num['B']*num['E'][E]*num['S'][S]*num['I'][I]*
num['G'][G]*num['O'][O]*num['M'][M];
}
}
cout<<result<<endl;

return0;
}


[b]PROBLEM
3TRAPPEDINTHEHAYBALES


FJ收到了N个大干草捆(1<N<4000)然后将这些干草随意的放在放到通往养牛场的路的任意位置上。不幸的是,他忘了奶牛Bessie正在路上散步,她有可能被这些捆困住。

每个捆j的大小为S_j,在某个独特的位置P_j处,这个位置是一维马路上的一点。奶牛Bessie从一个没有草堆的地方出发, 他可以自由的在这条马路上走来走去,甚至走到某一捆干草所在的位置,但她不能穿过那个点。但有个例外,如果她朝着一个方向跑D各单位的距离,她可以积攒到足够的速度冲破一个大小小于D的干草捆, 这之后,那个干草捆就永远的被消灭了。当然,这之后,她可能开拓了更多的空间,使她可以跑向其他的干草捆, 并消灭这些捆。

Bessie如果她最终突围了最左边或最右边的任意一个甘草捆,她就逃脱了。请计算出路上Bessie无法逃脱的起始位置的总面积。比如说,如果Bessie的起始位置是在两捆之间从1到5的位置上,而且在这中间Bessie无法逃脱,那么她无法逃脱的面积就为4。

输入格式:(trapped.in

第一行包括数字N,接下来的N行每行表示一个干草捆,包括两个整数,分别表示这个捆的大小和位置。每个值在1~10^9之间。

输出格式:(trapped.out

输出一个整数,表示Bessie在这条路上无法逃脱的起始位置的面积。

输入样例:

5
81
14
88
715
420


输出样例:

14

【题目分析】
这题有一个很简单的解法,那就是不停的算两边的干草堆是否能够突破,然后不断突破,直到破出来为止,大概是O(n)的算法,非常之简单。
【代码】
见我的三四题翻译:http://wenjianwei1.blog.163.com/blog/static/183193331201581942044330/

PROBLEM4PALINDROMIC
PATHS


FJ的农场是一个N*N格子形状的一块地(2<N<18),每个格子用一个字母表示,比如:

ABCD
BXZX
CDXB
WCBA


每天,Bessie奶牛从左上角走向右下角,她每一步可以向右或向下走。Bessie记录着她走的过程中所产生的字符串。她的方向感很差,所以生成出来的字符串要是回文串(从前和从后读是一样的),
因为她不记得她曾经走过的方向。

帮Bessie她可以走出的不同的回文串的个数。沿不同路径走出的相同的回文串只算一次。比如说,上面的例子中有多种不同的路径可以产生出回文串ABXZXBA,但Bessie只能走出四种不同的回文串:ABCDCBA,ABCWCBA,
ABXZXBA,ABXDXBA。

输入格式:(palpath.in

第一行包括一个整数N,剩下的N行每行包括N个在A-Z之间的字符,表示这块农场。

输出格式:(palpath.out

输出Bessie可能走出的不同的回文串的个数。

输入样例:

4
ABCD
BXZX
CDXB
WCBA


输出样例:

4
【题目分析】 这题就不用怎么说了,直接枚举,因为规模很小,可以直接列出从左上角和右下角所能产生的字符串(到对角线),接着做两个产生字符串的集合的交集,求总大小就可以了。
【代码】 具体看三四题的翻译代码:http://wenjianwei1.blog.163.com/blog/static/183193331201581942044330/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: