纪中模拟赛——普及
2018-01-26 19:38
176 查看
第一题(手机):
一般的手机的键盘是这样的:1 2abc 3def
4ghi 5jkl 6mno
7pqrs 8tuv 9wxyz
要按出英文字母就必须要按数字键多下。例如要按出 x 就得按 9 两下,第一下会出 w,而第二下会把 w 变成 x。 0 键按一下会出一个空格。
你的任务是读取若干句只包含英文小写字母和空格的句子,求出要在手机上打出这个句子至少需要按多少下键盘。
输入
输入文件只包含一行,表示一个句子,句子中只包含英文小写字母和空格,且不超过200 个字符。
输出
一行一个整数,表示按键盘的总次数。
样例输入
i have a dream
样例输出
23
数据范围限制
【数据范围】
不超过 200 个字符。
解题思路:
暴力模拟————源程序:
#include <cstdio> #include <cstring> using namespace std; char c; int ans,i,n[27]={0,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,1,2,3,1,2,3,4};//a,b,c……x,y,z等需要按得次数。 int main() { /*freopen("mobile.in","r",stdin); freopen("mobile.out","w",stdout);*/ while ((c=getchar())!='\n') //输入 { if (c==' ') ans++;//空格+1 else ans+=n[c-96]; //只有小写字母 } printf("%d",ans);//输出 return 0; }
第二题(游戏):
Atlantis Island 沉没以前,传说中的猫老大和 King 是好朋友……King 很喜欢赌博,这次 King和老朋友猫老大多年不见, 于是便邀请猫老大来玩一个游戏,猫老大应邀参加了。 King 拿出了 n 块黄金(0解题思路:
某大佬讲题:“数据这么大,要不找规律,要不特殊算法!” 那我们就来找找规律吧。 1时输出:MaoLaoDa will win. 1 2时输出:MaoLaoDa will win. 2 3时输出:King will win. 4时输出:MaoLaoDa will win. 1 5时输出:MaoLaoDa will win. 2 6时输出:King will win. 7时输出:MaoLaoDa will win. 1 8时输出:MaoLaoDa will win. 2 9时输出:King will win. So,可以看出模3取余就可以算出————如果模3得0则King赢,否则是猫老大赢,而且先取模3得出的结果个黄金。 但是,数据这么大,怎么处理呢?记得小学学过的东西吗?怎么判断是否是3的倍数————每一位的数字和,如果是3的倍数,那么这个数就是三的倍数。
源程序:
#include <cstdio> #include <string> #include <iostream> using namespace std; string c;//用字符数组会超时 int main() { freopen("atlantis.in","r",stdin); freopen("atlantis.out","w",stdout); for (int i=1;i<=3;i++) { cin>>c;//scanf读入不了 int ans=0; for (int j=0;j<c.size();j++) ans+=c[j]-48;//将这个数每位得数字相加 if (ans%3==0) printf("King will win.\n");//判断 else printf("MaoLaoDa will win.\n%d\n",ans%3);//判断 } }
第三题(家族):
在一个与世隔绝的岛屿上,有一个有趣的现象:同一个家族的人家总是相邻的(这里的相邻是指东南西北四个方向),不同的家族之间总会有河流或是山丘隔绝,但同一个家族的人不一定有相同姓氏。现在给你岛上的地图,求出岛上有多少个不同的家族。岛上的地图有n 行,每行有若干列,每个格子中要么是’空格表示大海,要么是‘ *’,表示河流或山丘,要么是小写字母,表示一户人家的姓氏。输入
第一行是个数字 N,表示下面信息的行数,接下来是 N 行字符,每行由小写字母和*号组成,有些行的最前面也可能包含若干连续的空格,表示这些区域是大海,每一行最多不超过 200 个字符。
输出
一个数字,表示家族数。
样例输入
4
*zlw**pxh
l*zlwk*hx*
w*tyy**yyy
zzl
样例输出
3
数据范围限制
【数据范围】
10%的数据, n<=1
30%的数据, n<=10
100% 的数据, n<=100 每一行最多不超过 200 个字符
解题思路:
这题数据比较弱,bfs(广搜)和dfs(深搜)都可以。我用得是广搜(快嘛!)。
源程序:
#include <cstdio> using namespace std; char c; int ans,o,n,a[101][201],dx[5]={0,1,-1,0,0},dy[5]={0,0,0,1,-1},father[20001],state[20001][3]; void bfs(int x,int y)//广搜 { int p,head=0,tail=1; a[x][y]=0;state[1][1]=x;state[1][2]=y; do { head++; for (int i=1;i<=4;i++) 4000 { int x=state[head][1]+dx[i]; int y=state[head][2]+dy[i]; if (x>0&&y>0&&x<=n&&y<=o&&a[x][y]) //每找到一个连在一起的家 { tail++; father[tail]=head; state[tail][1]=x; state[tail][2]=y; a[x][y]=0; //就把它变成河(山)流(丘),以免重复 } } } while(head<tail); } int main() { //freopen("family.in","r",stdin); //freopen("family.out","w",stdout); scanf("%d",&n); //一开始就卡着,没打\n,后来补上,发现————还是错的 for (int i=0;i<=n;i++)//So我就把1..n改为0..n { o=0; while((c=getchar())!='\n') { o++; if (c>='a'&&c<='z') a[i][o]=1; else a[i][o]=0; } } //接着一系列读入 o=200; //把每一行读入得字符长度变得相同(应该比较好做) for (int i=1;i<=n;i++) for (int j=1;j<=o;j++) if (a[i][j]) //如果不是河(山)(海)流(丘),就来一次bfs { bfs(i,j);//bfs不解释 ans++;//连在一起的家族 总数+1 } printf("%d",ans);//输出 }
第四题(作业):
光光上了高中,科目增多了。在长假里,光光的老师们都非常严厉,都给他布置了一定量的作业。假期里,光光一共有的时间是 k 小时。在长假前,老师们一共给光光布置了 n份作业,第 i 份作业需要的时间是 ti 小时。但是由于老师们互相不商量,因此光光有可能不能完成老师的作业。当可能不能完成老师的作业时,光光就事后去向老师说明,然后被老师批评一顿了事。对于一件作业,只有 2 种情况:完成或者不完成(快要完成也算不完成)。如果没完成,受到批评是天经地义的。但是,不同的作业对于光光来说,批评的力度是不同的。第 i 件作业如果没完成,就要受到 pi 个单位的批评。多次这样之后,光光想要在长假前就知道他至少会受到多少个单位的批评。你能帮助他吗?
输入
输入文件的第一行只有一个数字 k。
第二行只有一个数字 n。
接下来 n 行,每行两个数字,分别是 ti 和 pi,两个数字之间用一个空格分开。
输出
输出文件 homework.out 仅包含一行,是一个数字,代表了光光最少受到的批评。
样例输入
5
3
2 6
1 3
4 7
样例输出
6
数据范围限制
【数据范围】
100%的数据中, k<=100000, ti<=10000, pi<=10000;
30%的数据中, n<=20;
100%的数据中, n<=500。
解题思路:
数据也不大,普通的01背包。
动态转移方程:f[v]=max(f[v-w[i]]+c[i],f[v]);
源程序:
#include<cstdio> using namespace std; int n,m,ans,f[100001],w[501],c[501]; int max(int x,int y)//max函数不解释 { return x>y?x:y; } int main() { freopen("homework.in","r",stdin); freopen("homework.out","w",stdout); scanf("%d%d",&m,&n); for (int i=1;i<=n;i++) { scanf("%d%d",&w[i],&c[i]);//w表示要用的时间,c表示(没)做完(可以)免(受)掉(到)的批评 ans+=c[i];//先把所有加起来,作用————后面再说 } for (int i=1;i<=n;i++) for (int v=m;v>=w[i];v--) f[v]=max(f[v-w[i]]+c[i],f[v]);//就是01背包————不懂得————没办法 printf("%d",ans-f[m]);//用批评总量减去写完的科目的批评总量,得出结果 return 0; }
相关文章推荐
- 纪中训练 day5 【NOIP普及组】模拟赛D组 解题报告
- 2018.01.31【NOIP普及组】模拟赛D组
- 纪中训练 day8 【NOIP普及组】模拟赛D组 解题报告
- JZOJ(中山纪念中学) 2018.02.02【NOIP普及组】模拟赛D组
- 2018.02.02【NOIP普及组】模拟赛D组
- 2017.1.13【初中部 】普及组模拟赛C组 money 最小花费 题解
- 2017.03.18【NOIP 普及组】模拟赛C组 数列 题解
- 2017.08.15【NOIP 普及组】模拟赛C组总结
- 2017.09.09【NOIP 普及组】模拟赛C组
- 纪中训练 day1 【NOIP普及组】模拟赛D组 解题报告
- JZOJ(中山纪中)2018.01.21【NOIP普及组】模拟赛D组(第一题)
- JZOJ(中山纪中) 2018.02.01【NOIP普及组】模拟赛D组 第二题
- 纪中训练 day10【NOIP普及组】模拟赛D组 解题报告
- 2018.02.03【NOIP普及组】模拟赛D组
- 【普及组模拟赛】Note
- 2017.03.10【NOIP 普及组】模拟赛C组 三条直线Three lines 题解
- 2017.03.18【NOIP 普及组】模拟赛C组
- 2017.03.18【NOIP 普及组】模拟赛C组 蚂蚁 题解
- JZOJ1422.2017.03.25【NOIP 普及组】模拟赛C组 T4步行