棋盘解题报告(noip2017普及组第三题)

棋盘解题报告(noip2017普及组第三题)
棋盘解题报告(noip2017普及组第三题)

棋盘解题报告(noip2017普及组第三题)上次写了Linux用vim进行C++编程的配置和操作入门后,今天再给棋盘写个解题报告试试。

题目描述

有一个m ×m的棋盘,棋盘上每一个格子可能是红色、黄色或没有任何颜色的。你现在要从棋盘的最左上角走到棋盘的最右下角。

任何一个时刻,你所站在的位置必须是有颜色的(不能是无色的),你只能向上、下、左、右四个方向前进。当你从一个格子走向另一个格子时,如果两个格子的颜色相同,那你不需要花费金币;如果不同,则你需要花费1 个金币。另外,你可以花费2 个金币施展魔法让下一个无色格子暂时变为你指定的颜色。但这个魔法不能连续使用,而且这个魔法的持续时间很短,也就是说,如果你使用了这个魔法,走到了这个暂时有颜色的格子上,你就不能继续使用魔法;只有当你离开这个位置,走到一个本来就有颜色的格子上的时候,你才能继续使用这个魔法,而当你离开了这个位置(施展魔法使得变为有颜色的格子)时,这个格子恢复为无色。

现在你要从棋盘的最左上角,走到棋盘的最右下角,求花费的最少金币是多少?输入输出格式

输入格式:

数据的第一行包含两个正整数m,n,以一个空格分开,分别代表棋盘的大小,棋盘上有颜色的格子的数量。

接下来的n 行,每行三个正整数x,y,c,分别表示坐标为(x,y)的格子有颜色c。

其中c=1 代表黄色,c=0 代表红色。相邻两个数之间用一个空格隔开。棋盘左上角的坐标为(1, 1),右下角的坐标为(m, m)。

棋盘上其余的格子都是无色。保证棋盘的左上角,也就是(1,1)一定是有颜色的。

输出格式:

输出一行,一个整数,表示花费的金币的最小值,如果无法到达,输出-1。输入输出样例

输入样例#1:

5 7

1 1 0

1 2 0

2 2 1

3 3 1

3 4 0

4 4 1

5 5 0

输出样例#1:

8

输入样例#2:

5 5

1 1 0

1 2 0

2 2 1

3 3 1

5 5 0

输出样例#2:

-1

说明

输入输出样例1 说明

从(1,1)开始,走到(1,2)不花费金币

从(1,2)向下走到(2,2)花费1 枚金币

从(2,2)施展魔法,将(2,3)变为黄色,花费2 枚金币从(2,2)走到(2,3)不花费金币

从(2,3)走到(3,3)不花费金币

从(3,3)走到(3,4)花费1 枚金币

从(3,4)走到(4,4)花费1 枚金币

从(4,4)施展魔法,将(4,5)变为黄色,花费2 枚金币,

从(4,4)走到(4,5)不花费金币

从(4,5)走到(5,5)花费1 枚金币

共花费8 枚金币。

输入输出样例2 说明

从(1,1)走到(1,2),不花费金币

从(1,2)走到(2,2),花费1 金币

施展魔法将(2,3)变为黄色,并从(2,2)走到(2,3)花费2 金币从(2,3)走到(3,3)不花费金币

从(3,3)只能施展魔法到达(3,2),(2,3),(3,4),(4,3)

而从以上四点均无法到达(5,5),故无法到达终点,输出-1

数据规模与约定

对于30%的数据,1 ≤m ≤5,1 ≤n ≤10。

对于60%的数据,1 ≤m ≤20,1 ≤n ≤200。

对于100%的数据,1 ≤m ≤100,1 ≤n ≤1,000。

解题报告

这道题目是2017年普及组第三题,实质上是求矩阵中一个点到另一个点的最短路径,对于这类型的题目,通常可以用搜索的方法来完成,深度优先和广度优先都行,广度优先需要使用队列,稍微复杂一点,我这里就用深搜来完成。

1、输入数据,构造棋盘,总共三种颜色,0表示红色,1表示黄色,-1表示无色;

2、从(1,1)点开始,往上下左右四个方向去搜索,这里和普通的只能往右和左搜索的题目有点不同,在普通的搜索里面,到达了一个点就设一个标志变量,然后下次就不再搜索这个节点,但是这里不能这么简单的处理,因为每个节点可以往上下左右四个方向搜索,如果不设标志则会形成死循环,出不来,设个标志则有可能从不同的路径走到这个点的花费可能不相同,第一次的花费不一定是最低的。那么我们就把进到这个节点的花费记录下来,下次进入这个节点时候,比较一下花费,如果相同或者大于上次花费,就不用搜索这个节点,否则就继续搜索他,我们把这种方法叫做记忆化搜索。

3、对于魔法问题,我们采用一点贪心策略,碰到一个无色格子,就让他变得和当前格子颜色一样,再到深搜递归函数里面加上一个参数,来表示魔法状态,如果上次已经使用了魔法,而当前格子是无色,也需要使用魔法,因为不能两次使用魔法,就直接返回。

4、当走到了右下角(m,m)点,说明已经找到了一条路径,把花费最小那条路径记录下来就OK了。

这道题目还是比较简单的,具体看代码:

#include

#include

#include

using namespace std;

int a[102][102],v[102][102],n,m,ans=999999;

int dx[]={0,1,0,-1},dy[]={1,0,-1,0};//按右下左上搜索

//搜索单元格(x,y),从(1,1)到上一单元已花费val

//上个单元颜色为c,上单元是否使用魔法mo

void dfs(int x, int y, int val, int c, bool mo)

{

if(a[x][y] == -1 && mo)//不能两次魔法

return;

if(x==m&&y==m)

{

if(a[m][m] != c)

{

temp++;

if(a[m][m]==-1)//变魔法,在原来基础上再加1 temp++;

}

if(temp

ans=temp;

return;

}

if(a[x][y]==-1)

{

val += 2;

mo=1;

}

else

{

mo=0;

if(a[x][y] != c)

{

val += 1;

}

}

if(val>=v[x][y] || val>=ans)

{

return;

}

else

{

v[x][y] = val;

int xx,yy;

for(int i=0; i<4; i++)

{

xx=x+dx[i];

yy=y+dy[i];

if(xx>=1&&xx<=m&&yy>=1&&yy<=m)

dfs(xx,yy,val,c,mo);

}

}

}

int main()

{

int i, x, y, k;

cin>>m>>n;

memset(a, -1, sizeof(a));//把a数组全部设为-1表示没有颜色memset(v, 127, sizeof(v));//把v数组设为一个巨大的数字

for(i=0; i

{

scanf("%d%d%d", &x,&y,&k);

a[x][y] = k;

}

dfs(1,1,0,a[1][1],0);

if(ans==999999)

cout<<-1;

else

cout<

}

棋盘解题报告(noip2017普及组第三题)

棋盘解题报告(noip2017普及组第三题)上次写了Linux用vim进行C++编程的配置和操作入门后,今天再给棋盘写个解题报告试试。 题目描述 有一个m ×m的棋盘,棋盘上每一个格子可能是红色、黄色或没有任何颜色的。你现在要从棋盘的最左上角走到棋盘的最右下角。 任何一个时刻,你所站在的位置必须是有颜色的(不能是无色的),你只能向上、下、左、右四个方向前进。当你从一个格子走向另一个格子时,如果两个格子的颜色相同,那你不需要花费金币;如果不同,则你需要花费1 个金币。另外,你可以花费2 个金币施展魔法让下一个无色格子暂时变为你指定的颜色。但这个魔法不能连续使用,而且这个魔法的持续时间很短,也就是说,如果你使用了这个魔法,走到了这个暂时有颜色的格子上,你就不能继续使用魔法;只有当你离开这个位置,走到一个本来就有颜色的格子上的时候,你才能继续使用这个魔法,而当你离开了这个位置(施展魔法使得变为有颜色的格子)时,这个格子恢复为无色。 现在你要从棋盘的最左上角,走到棋盘的最右下角,求花费的最少金币是多少?输入输出格式 输入格式:

数据的第一行包含两个正整数m,n,以一个空格分开,分别代表棋盘的大小,棋盘上有颜色的格子的数量。 接下来的n 行,每行三个正整数x,y,c,分别表示坐标为(x,y)的格子有颜色c。 其中c=1 代表黄色,c=0 代表红色。相邻两个数之间用一个空格隔开。棋盘左上角的坐标为(1, 1),右下角的坐标为(m, m)。 棋盘上其余的格子都是无色。保证棋盘的左上角,也就是(1,1)一定是有颜色的。 输出格式: 输出一行,一个整数,表示花费的金币的最小值,如果无法到达,输出-1。输入输出样例 输入样例#1: 5 7 1 1 0 1 2 0 2 2 1 3 3 1 3 4 0 4 4 1 5 5 0 输出样例#1: 8 输入样例#2: 5 5

noip2014普及组复赛题解

1.珠心算测验 注意看清题意:其中有多少个数,恰好等于集合中另外两个(不同 的)数之和。这样的题意加上100的规模,建议暴力3个for: #include #include #include #include using namespace std; int n; int a[105]; int main(){ freopen("count.in","r",stdin); freopen("count.out","w",stdout); scanf("%d",&n); for(int i=1; i<=n; i++){ scanf("%d",&a[i]); } sort(a+1,a+n+1); int res=0; for(int i=1; i<=n; i++){ int ok=0; for(int j=1; j<=n && !ok; j++) if(j!=i){ for(int k=1; k<=n && !ok; k++) if(a[k]!=a[j]){ if(a[j]+a[k]==a[i]) ok=1; } } res+=ok; } printf("%d\n",res); return 0; } 2.比例简化 L很小,还是枚举,然后比较的话建议用乘法比较,避免精度问题:#include #include #include using namespace std; int A,B,L; int gcd(int a,int b){ if(b==0) return a; return gcd(b,a%b); } int main(){ freopen("ratio.in","r",stdin); freopen("ratio.out","w",stdout); scanf("%d%d%d",&A,&B,&L); int ba=1000000,bb=1; for(int i=1; i<=L; i++){ for(int j=1; j<=L; j++){ if(gcd(i,j)==1 && i*B>=j*A){

NOIP2015普及组解题报告

NOIP2015 普及组解题报告 From 贴吧id u007zzt 金币 国王将金币作为工资,发放给忠诚的骑士。 第一天骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天,每天收到四枚金币,以此类推;这种工资发放模式会一直延续下去,当连续N天收到N枚金币后,骑士会在之后的N+1天,每天收到N+1枚金币。 请计算前K天里,骑士一共获得了多少金币。 输入格式 输入包含一个正整数K,表示发放金币的天数。 输出格式 输出一个正整数,即骑士收到的金币数。 样例1 样例输入1 6 样例输出1 14 样例2 样例输入2 1000 样例输出2 29820 对于全部数据,1≤K≤10000。 这种题目,简直就属于水题狂做的那种。不多说,附C++代码。 #include "stdio.h" int k,ans=0; int main(){ freopen("coin.in","r",stdin); freopen("coin.out","w",stdout); scanf("%d",&k); int i=1; while(k){ if(k>=i){ ans+=i*i; k-=i; }else{ ans+=k*i; k=0;

} i++; } printf("%d\n",ans); return 0; } 扫雷游戏 扫雷游戏是一款十分经典的单机小游戏。 在n行m列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。 玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。 游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格。 现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格周围的地雷格数。 注:一个格子的周围格子包括其上、下、左、右、左上、左下、右上、右下八个方向上与之直接相邻的格子。 输入格式 第一行用一个空格隔开的两个整数n和m,分别表示雷区的行数和列数。 接下来n行,每行m个字符,描述了雷区中的地雷分布情况。字符?'表示相应的格子是地雷格,字符(?)`表示相应的格子是非地雷格子。相邻字符之间无分隔符。 输出格式 输出文件包括n行,每行m个字符,描述了整个雷区。用?表示地雷格,用周围地雷格数表示非地雷格。相邻字符之间无分隔符。 样例1 样例输入1 3 3 *?? ??? ?*? 样例输出1 *10 221 1*1 样例2 样例输入2 2 3 ?*? *?? 样例输出2 2*1 *21

NOIP普及组复赛解题报告

NOIP2015 普及组解题报告 南京师范大学附属中学树人学校CT 1.金币(coin.cpp/c/pas) 【问题描述】国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金 币;这种工资发放模式会一直这样延续下去:当连续N天每天收到N枚金 币后,骑士会在之后的连续N+1天里,每天收到N+1枚金币。 请计算在前K 天里,骑士一共获得了多少金币。【输入格式】 输入文件名为coin.in 。 输入文件只有1行,包含一个正整数K,表示发放金币的天数。 【输出格式】 输出文件名为coin.out。 输出文件只有1 行,包含一个正整数,即骑士收到的金币数。 【数据说明】 对于100%的数据,1 < K < 10,000 【思路】 模拟 【时空复杂度】 O(k) ,O(1) 2 、扫雷游戏(mine.cpp/c/pas ) 【问题描述】

扫雷游戏是一款十分经典的单机小游戏。在n行m列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格。 现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格周围的地雷格数。注:一个格子的周围格子包括其上、下、左、右、左上、右上、左下、右下八个方向上与之直接相邻的格子。 【输入格式】 输入文件名为mine.in 。 输入文件第一行是用一个空格隔开的两个整数n和m分别表示雷区的行数和列数。 接下来n行,每行m个字符,描述了雷区中的地雷分布情况。字符’* '表示相应格子是地雷格,字符' ?'表示相应格子是非地雷格。相邻字符之间无分隔符。【输出格式】输出文件名为mine.out 。 输出文件包含n行,每行m个字符,描述整个雷区。用’* '表示地雷格,用周围的地雷个数表示非地雷格。相邻字符之间无分隔符。 【数据说明】 对于100% 的数据,1< n W 1Q01< me 100 【思路】 模拟 【技巧】 可将数组多开一圈,省去边界条件的判断 【时空复杂度】 O(mn),O(mn)

NOIP2015普及组复赛解题报告

精心整理 NOIP2015普及组解题报告 南京师范大学附属中学树人学校CT 1.金币(coin.cpp/c/pas) 【问题描述】 国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天) 放模式会一直这样延续下去:当连续N 续N+1天里,每天收到N+1枚金币。 请计算在前K 【输入格式】 输入文件名为coin.in。 输入文件只有1 【数据说明】 对于100%的数据,1≤K≤10,000。 【思路】 模拟 【时空复杂度】 O(k),O(1)

2、扫雷游戏(mine.cpp/c/pas) 【问题描述】 扫雷游戏是一款十分经典的单机小游戏。在n行m列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格。 现在给出n行m 向上与之直接相邻的格子。 【输入格式】 输入文件名为mine.in。 接下来n行,每行m 雷个数表示非地雷格。相邻字符之间无分隔符。 【数据说明】 对于100%的数据,1≤n≤100,1≤m≤100。 【思路】 模拟 【技巧】

可将数组多开一圈,省去边界条件的判断。【时空复杂度】 O(mn),O(mn)

3.求和(sum.cpp/c/pas) 【问题描述】 一条狭长的纸带被均匀划分出了n个格子,格子编号从1到n。每个格子上都染了一种颜色color i(用[1,m]当中的一个整数表示),并且写了一个数字number i。 定义一种特殊的三元组:(x,y,z),其中x,y,z都代表纸带上格子的编号,这里的三元组要求满足以下两个条件: 1.x,y,z都是整数,x

noip2017提高组复赛解题报告

noip2017提高组复赛解题报告 定期推送帐号信息学新闻,竞赛自主招生,信息学专业知识,信息学疑难解答,融科教育信息学竞赛培训等诸多优质内容的微信平台,欢迎分享文章给你的朋友或者朋友圈!以下解题思路及代码未经官方评测,仅供参考,复赛成绩以官方(CCF)评测结果为准。 Day1 1.小凯的疑惑(math.cpp/c/pas)【问题描述】小凯手中有两种面值的金币,两种面值均为正整数且彼此互素。每种金币小凯都有无数个。在不找零的情况下,仅凭这两种金币,有些物品他是无法准确支付的。现在小凯想知道在无法准确支付的物品中,最贵的价值是多少金币?注意:输入数据保证存在小凯无法准确支付的商品。【输入格式】输入文件名为math.in。输入数据仅一行,包含两个正整数a 和b,它们之间用一个空格隔开,表示小凯手中金币的面值。【输出格式】输出文件名为math.out。输出文件仅一行,一个正整数N,表示不找零的情况下,小凯用手中的金币不能准确支付的最贵的物品的价值。【输入输出样例1】math.in3 7 math.out11【数据规模与约定】对于30%的数据: 1 ≤a,b ≤50。对于60%的数据: 1 ≤a,b ≤10,000。对于100%的数据:1 ≤a,b ≤1,000,000,000。数学太差只找规律吧。

设:其中一个数为2则:2、3=>1;2、5=>3;2、7=>5;2、11=>9得:2、n=>n-2设:其中一个数为3则:3、5=>7;3、7=>11;3、11=>19;3、13=>23得:3、n=>2n-3设:其中一个数为5则:5、7=>23;5、11=>39;5、13=>47;5、17=>63得:5、n=>4n-5所以:m、n=>(m-1)n-m #includeusing namespace std;int main(){ long long a,m,n; scanf('%lld %lld',&m,&n); a=(m-1)*n-m; printf('%lld',a); return 0;} 2.时间复杂度(complexity.cpp/c/pas)【问题描述】小明正在学习一种新的编程语言A++,刚学会循环语句的他激动地写了好多程序并给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序,于是你的机会来啦!下面请你编写程序来判断小明对他的每个程序给出的时间复杂度是否正确。A++语言的循环结构如下:其中“F i x y”表示新建变量(i 变量i 不可与未被销毁的变量重名)并初始化为x,然后判断i 和y 的大小关系,若i 小于等于y 则进入循环,否则不进入。每次循环结束后i都会被修改成i +1,一旦i 大于y 终止循环。x和y 可以是正整数(x 和y 的大小关系不定)或变量n。n 是一个表示数据规模的变量,在时间复杂度计算中需保留该变量而不能将其视为常数,该数远大于100。“E”表示循环体结束。循环体结束时,这个循环体新建的变量也被销毁。注:本题中为了书写方便,在描述复杂度时,使用大

NOIP2017普及组复赛-解题报告

NOIP2017普及组复赛-解题报告 衢州市兴华中学 By 冯明浩 Score 成绩 题目大意 给出三个整十数A,B,C ,求A*20%+B*30%+C*50%的值 考察算法 模拟 算法一 直接粗暴地输出A*0.2+B*0.3+C*0.5 时间复杂度:O(1) 期望得分:100 算法二 由于分数均为整十数,先将分数各除以10,再直接输A*2+B*3+C*5。这样就避免了精度问题 时间复杂度:O(1) 期望得分:100 librarian 图书管理员 题目大意 给出N 个数Ai ,再进行Q 次询问,找后缀为给定数Bi 的最小的Ai 考察算法 模拟 算法一 将Ai 及Bi 都转化成字符串。每次询问都对N 个数进行后缀比较,挑出个最小的 时间复杂度:O(N*Q*len) 期望得分:80 算法二 对算法一的比较进行优化——构造出n 10,对于Ai ,直接Ai Mod 10len ,判断是否 相等。这样每次比较的时间复杂度优至O(1) 同时先将Ai 排序,再每次从小到大查询,一旦找到就停 时间复杂度:小于O(N*Q)(一般情况) 期望得分:100 算法三 读入Ai 时进行处理,构造ans[x]数组,记录询问X 的最小值。对于每个Ai ,依次 取出其后1、2、3……len 位,修正其的最小值。这样每次查询,就可以O (1)出结 果了 时间复杂度:O(N*len) 空间复杂度:O(max(Bi)) 期望得分:100 Chess 棋盘 题目大意 给出一个N*N 的矩阵,其中部分格有颜色 每次可以从一个格向上下左右四个方向移动一格(不能越出矩阵且满足条件),根据 两个格子的颜色有不同的代价 求从左上角走至右下角的最小代价 考察算法 最短路(动态规划) 算法一 直接暴力地按照题意进行DFS 时间复杂度:O(n n *2) 期望得分:30 算法二 以左上角为起点,右下角为终点,刷四个方向的SPFA

noip2015普及组题解最终分解

本次试题前2题比较简单,34题容易拿到部分分,但满分有难度1. 金币 (coin.cpp/c/pas) 【问题描述】 国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去:当连续N天每天收到N枚金币后,骑士会在之后的连续N+1天里,每天收到N+1枚金币。 请计算在前K天里,骑士一共获得了多少金币。 【输入格式】 输入文件名为coin.in。 输入文件只有1行,包含一个正整数K,表示发放金币的天数。 【输出格式】 输出文件名为coin.out。 输出文件只有1行,包含一个正整数,即骑士收到的金币数。 【样例输入】coin.in 6 【样例输出】coin.out 14 【输入输出样例1说明】 骑士第一天收到一枚金币;第二天和第三天,每天收到两枚金币;第四、五、六天,每天收到三枚金币。因此一共收到1+2+2+3+3+3=14枚金币。 【数据范围】对于100%的数据,1 ≤K ≤10,000。 【题解】 关注到K的范围是10000后,就不需要考虑数学公式,纯模拟就行,考点就是for循环了 var i,j,count,n,ans:longint; begin assign(input,'coin.in');reset(input); assign(output,'coin.out');rewrite(output); readln(n); for i:=1 to 1000 do for j:=1 to i do begin inc(count); inc(ans,i); if count=n then begin writeln(ans); close(input);close(output); halt;

noip普及组复赛解题报告

N O I P2015普及组解题报告 南京师范大学附属中学树人学校CT 1.金币(coin.cpp/c/pas) 【问题描述】 国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去:当连续N天每天收到N枚金币后,骑士会在之后的连续N+1天里,每天收到N+1枚金币。 请计算在前K天里,骑士一共获得了多少金币。 【输入格式】 输入文件名为coin.in。 输入文件只有1行,包含一个正整数K,表示发放金币的天数。 【输出格式】 输出文件名为coin.out。 输出文件只有1行,包含一个正整数,即骑士收到的金币数。 【数据说明】 对于100%的数据,1≤K≤10,000。 【思路】 模拟 【时空复杂度】

O(k),O(1)

2、扫雷游戏(mine.cpp/c/pas) 【问题描述】 扫雷游戏是一款十分经典的单机小游戏。在n行m列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格。 现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格周围的地雷格数。 注:一个格子的周围格子包括其上、下、左、右、左上、右上、左下、右下八个方向上与之直接相邻的格子。 【输入格式】 输入文件名为mine.in。 输入文件第一行是用一个空格隔开的两个整数n和m,分别表示雷区的行数和列数。 接下来n行,每行m个字符,描述了雷区中的地雷分布情况。字符’*’表示相应格子是地雷格,字符’?’表示相应格子是非地雷格。相邻字符之间无分隔符。 【输出格式】 输出文件名为mine.out。 输出文件包含n行,每行m个字符,描述整个雷区。用’*’表示地雷格,用周围的地雷个数表示非地雷格。相邻字符之间无分隔符。 【数据说明】

NOIP2008普及组复赛试题与解题报告

NOIP 2008普及组解题报告 一、ISBN号码(isbn.pas/c/cpp) 【问题描述】 每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字、1位识别码和3位分隔符,其规定格式如“x-xxx-xxxxx-x”,其中符号“-”是分隔符(键盘上的减号),最后一位是识别码,例如0-670-82162-4就是一个标准的ISBN码。ISBN码的首位数字表示书籍的出版语言,例如0代表英语;第一个分隔符“-”之后的三位数字代表出版社,例如670代表维京出版社;第二个分隔之后的五位数字代表该书在出版社的编号;最后一位为识别码。 识别码的计算方法如下: 首位数字乘以1加上次位数字乘以2……以此类推,用所得的结果mod 11,所得的余数即为识别码,如果余数为10,则识别码为大写字母X。例如ISBN号码0-670-82162-4中的识别码4是这样得到的:对067082162这9个数字,从左至右,分别乘以1,2,…,9,再求和,即0×1+6×2+……+2×9=158,然后取158 mod 11的结果4作为识别码。 你的任务是编写程序判断输入的ISBN号码中识别码是否正确,如果正确,则仅输出“Right”;如果错误,则输出你认为是正确的ISBN号码。 【输入】 输入文件isbn.in只有一行,是一个字符序列,表示一本书的ISBN号码(保证输入符合ISBN号码的格式要求)。 【输出】 输出文件isbn.out共一行,假如输入的ISBN号码的识别码正确,那么输出“Right”,否则,按照规定的格式,输出正确的ISBN号码(包括分隔符“-”)。 【输入输出样例1】 isbn.in 0-670-82162-4 isbn.out Right 【输入输出样例2】 isbn.in

noip2008普及组复赛试题(附题解)

全国信息学奥林匹克联赛(NOIP2008)复赛 普及组 注意事项: 1、文件名(程序名和输入输出文件名)必须使用小写。 2、C/C++中函数main()的返回值类型必须是int,程序正常结束时的返回值必须是0。 3、全国统一评测时采用的机器配置为:CPU 1.9GHz,内存512M,上述时限以此配置为准。 各省在自测时可根据具体配置调整时限。

1.ISBN号码 (isbn.pas/c/cpp) 【问题描述】 每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字、1位识别码和3位分隔符,其规定格式如“x-xxx-xxxxx-x”,其中符号“-”是分隔符(键盘上的减号),最后一位是识别码,例如0-670-82162-4就是一个标准的ISBN码。ISBN码的首位数字表示书籍的出版语言,例如0代表英语;第一个分隔符“-”之后的三位数字代表出版社,例如670代表维京出版社;第二个分隔之后的五位数字代表该书在出版社的编号;最后一位为识别码。 识别码的计算方法如下: 首位数字乘以1加上次位数字乘以2......以此类推,用所得的结果mod 11,所得的余数即为识别码,如果余数为10,则识别码为大写字母X。例如ISBN号码0-670-82162-4中的识别码4是这样得到的:对067082162这9个数字,从左至右,分别乘以1,2, (9) 再求和,即0×1+6×2+……+2×9=158,然后取158 mod 11的结果4作为识别码。 你的任务是编写程序判断输入的ISBN号码中识别码是否正确,如果正确,则仅输出“Right”;如果错误,则输出你认为是正确的ISBN号码。 【输入】 输入文件isbn.in只有一行,是一个字符序列,表示一本书的ISBN号码(保证输入符合ISBN号码的格式要求)。 【输出】 输出文件isbn.out共一行,假如输入的ISBN号码的识别码正确,那么输出“Right”,否则,按照规定的格式,输出正确的ISBN号码(包括分隔符“-”)。 2.排座椅 (seat.pas/c/cpp) 【问题描述】 上课的时候总有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情。不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来之后,只有有限的D对同学上课时会交头接耳。同学们在教室中坐成了M行N列,坐在第i行第j列

NOIP2012普及组复赛解题报告c++版本

信息学奥赛NOIP2012普及组解题报告(c++版本) 第一题质因数分解, 题目已知正整数n是两个不同的质数的乘积, 试求出较大的那个质数, 没什么技术含量, 直接开个根号搜一遍就好了. 另外不开根号会TLE导致得60分. 1 #include 2 #include 3int main() 4 { 5int n; 6scanf("%d", &n); 7for (int i = 2, k = sqrt(n) + 1; i < k; ++i) 8if (n % i == 0) 9{ 10printf("%d\n", n / i); 11break; 12} 13return0; 14 } 第二题寻宝 [题目]传说很遥远的藏宝楼顶层藏着诱人的宝藏。小明历尽千辛万苦终于找到传说中的这个藏宝楼,藏宝楼的门口竖着一个木板,上面写有几个大字:寻宝说明书。说明书的内容如下:藏宝楼共有N+1层,最上面一层是顶层,顶层有一个房间里面藏着宝藏。除了顶层外,藏宝楼另有N层,每层M个房间,这M个房间围成一圈并按逆时针方向依次编号为0,…,M-1。其中一些房间有通往上一层的楼梯,每层楼的楼梯设计可能不同。每个房间里有一个指示牌,指示牌上有一个数字x,表示从这个房间开始按逆时针方向选择第x个有楼梯的房间(假定该房间的编号为k),从该房间上楼,上楼后到达上一层的k号房间。比如当前房间的指示牌上写着2,则按逆时针方向开始尝试,找到第2个有楼梯的房间,从该房间上楼。如果当前房间本身就有楼梯通向上层,该房间作为第一个有楼梯的房间。寻宝说明书的最后用红色大号字体写着:“寻宝须知:帮助你找到每层上楼房间的指示牌上的数字(即每层第一个进入的房间内指示牌上的数字)总和为打开宝箱的密钥”。请帮助小明算出这个打开宝箱的密钥。 这个题是个简单的模拟, 但是出乎意料的恶心, 当年做这个题的时候爆零, 钛蒻了, 总感觉这个比第三题难. 1 #include 2int x[10003][103], fjx[103]; 3bool k[10003][103]; 4int main()

noip2015普及组解题报告

1. 金币 (coin.cpp/c/pas) 【问题描述】国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去:当连续N天每天收到N枚金币后,骑士会在之后的连续N+1天里,每天收到N+1枚金币。 请计算在前K天里,骑士一共获得了多少金币。 【输入格式】输入文件名为coin.in。 输入文件只有1行,包含一个正整数K,表示发放金币的天数。 【输出格式】输出文件名为coin.out。 输出文件只有1行,包含一个正整数,即骑士收到的金币数。 【样例输入】coin.in 6 【样例输出】coin.out 14 【输入输出样例1说明】骑士第一天收到一枚金币;第二天和第三天,每天收到两枚金币;第四、五、六天,每天收到三枚金币。因此一共收到1+2+2+3+3+3=14 枚金币。 【数据范围】对于100%的数据,1 ≤K ≤10,000。 【题解】 纯模拟,直接爆搜,考点就是 for 循环 #include "stdio.h" #include "iostream" using namespace std; int main(){ freopen("coin.in","r",stdin); freopen("coin.out","w",stdout); int n,i=1,ans=0; cin>>n; while(n){ if(n>=i){ n-=i; ans+=i*i; }else{ ans+=i*n; n=0; } i++; } cout<

NOIP2015普及组复赛解题报告

NOIP2015普及组解题报告 南京师范大学附属中学树人学校CT 1. 金币(coin.cpp/c/pas) 【问题描述】 国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去:当连续N天每天收到N枚金币后,骑士会在之后的连续N+1天里,每天收到N+1枚金币。 请计算在前K天里,骑士一共获得了多少金币。 【输入格式】 输入文件名为coin.in。 输入文件只有1行,包含一个正整数K,表示发放金币的天数。【输出格式】 输出文件名为coin.out。 输出文件只有1行,包含一个正整数,即骑士收到的金币数。 【数据说明】 对于100%的数据,1 ≤K ≤10,000。 【思路】 模拟 【时空复杂度】 O(k),O(1)

2、扫雷游戏(mine.cpp/c/pas) 【问题描述】 扫雷游戏是一款十分经典的单机小游戏。在n行m列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格。 现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格周围的地雷格数。 注:一个格子的周围格子包括其上、下、左、右、左上、右上、左下、右下八个方向上与之直接相邻的格子。 【输入格式】 输入文件名为mine.in。 输入文件第一行是用一个空格隔开的两个整数n和m,分别表示雷区的行数和列数。 接下来n行,每行m个字符,描述了雷区中的地雷分布情况。字符’*’表示相应格子是地雷格,字符’?’表示相应格子是非地雷格。相邻字符之间无分隔符。 【输出格式】 输出文件名为mine.out。 输出文件包含n行,每行m个字符,描述整个雷区。用’*’表示地雷格,用周围的地雷个数表示非地雷格。相邻字符之间无分隔符。 【数据说明】

NOIP2017普及组解题报告非官方

NOIP2017普及组解题报告-by郑佳睿 1. 成绩(score.cpp/c/pas) 【问题描述】 牛牛最近学习了C++入门课程,这门课程的总成绩计算方法是: 总成绩= 作业成绩×20% + 小测成绩×30% + 期末考试成绩×50% 牛牛想知道,这门课程自己最终能得到多少分。 【输入格式】 输入文件只有1 行,包含三个非负整数A、B、C,分别表示牛牛的作业成绩、小测 成绩和期末考试成绩。相邻两个数之间用一个空格隔开,三项成绩满分都是100 分。 【输入样例1】 100 100 80 【输出样例1】 90 【输入样例2】 60 90 80 【输出样例2】 79 【数据说明】 30% 的数据,A = B = 0。 对于另外30% 的数据,A = B = 100。 对于100% 的数据,0 ≤A、B、C ≤100 且A、B、C 都是10 的整数倍。 【题解】 超级水题,输入数据都是10的倍数,不用考虑浮点的问题,直接输出答案。 【代码】 #include using namespace std; inta,b,c; int main(){ cin>>a>>b>>c; cout<<(a*2+b*3+c*5)/10<

NOIP2014复赛普及组第一题题解

活动园地 NOIP2014复赛普及组第一题题解原题

一、题目简化:求N个正数中有多少个数是这些数中其它两个数的和。 3<=N<=100; 每个正整数M:1<=M<=10000; 二、过程分析:试题显然可以分成三个步骤求解:1、先求出N个数中每两个数的 和;2、判断这些和中有没有重复,重复的数只留下一个;3、N个数中的每一个数都与这些和比较,若相等些记下,比较完成,即得其解。 三、算法与策略:三个步骤都采用一一列举所有可能的方法,是典型的枚举。 四、程序设计思路:1、一维数组A存放N个数,一维数组B存放两两相加的和; 求和、判断重复、比较两数是否相等,都采用两重循环,i 控制外循环,j 控 制内循环,k表示数组B的下标变化,ans表示题目答案。 数组a最多100个元素,考虑到用循环,为防止下标越界,可适当把数组开大一些,a[0..101];数组b中元素数是N个数两个数两两相加的和的个数,由于N最大是100,所以和的个数最多是1+2+3+……99=4950个,则b[0..5000]五、程序设计: program count; var a:array[0..101] of longint; b:array[0..5000] of longint; n,ans,i,j,k:longint; begin assign(input,'count.in'); reset(input); assign(output,'count.out'); rewrite(output); readln(n); for i:=1 to n do read(a[i]); fillchar(b,sizeof(b),0); **下面开始步骤1:a中的数两两相加放在b中** k:=1; for i:=1 to n-1 do for j:=i+1 to n do begin b[k]:=a[i]+a[j]; inc(k); end; **下面开始步骤2:筛掉b中的重

2012全国信息学联赛复赛普及组解题报告

质因数分解 (prime.cpp/c/pas) 【问题描述】 已知正整数n是两个不同的质数的乘积,试求出较大的那个质数。 【输入】 输入文件名为prime.in。 输入只有一行,包含一个正整数n。 【输出】 输出文件名为prime.out。 输出只有一行,包含一个正整数p,即较大的那个质数。 【输入输出样例】 prime.in prime.out 21 7 【数据范围】 对于60%的数据,6 ≤ n ≤ 1000。 对于100%的数据,6 ≤ n ≤ 2*109。 【算法分析】

这是一道基本题,“打底”的送分题,要注意的是数据的范围为长整型,考虑不超时不超空间。 算法1 枚举从大到小枚举出n所有的因子,如果这个因子是质数就是所求的最大质因子。也就是说,从n开始,看是否为质数,如果是则输出,结束;否则再看 n 能否被2整除,如能则看 n div 2是否是质数,如是则输出n div 2,结束;否则再看n能否被3整除……如此重复。 算法2,再接对n分解质因数,找到最大的质因数。分解质因子可以借助于“筛选法”的方法,对所有可能的质因子采用“筛选法”(n自身除外),分解后的最大质因子是最后一个约分质因子或者分解后剩下的不可再分解因子(哪个大取哪个)。 【参考程序】 算法1的程序 var n,i:longint; flag:boolean; function ok(x:longint):boolean;{判别x是否为质数的函数} var i:longint; begin i:=2; while (x mod i>0) and (i<=sqrt(x)) do inc(i); if i>sqrt(x) then exit(true) else exit(false); end; begin readln(n); i:=1; flag:=true; while flag and (i<=n/2) do begin if n mod i=0 then

NOIP2005普及组复赛试题(附题解)

noip2005普及组解题报告 陶陶摘苹果 【文件名】: apple.pas/c/cpp 【问题描述】 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果。苹果成熟的时候,陶陶就会跑去摘苹果。陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。 现在已知10个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,请帮陶陶算一下她能够摘到的苹果的数目。假设她碰到苹果,苹果就会掉下来。 【输入文件】 输入文件apple.in包括两行数据。第一行包含10个100到200之间(包括100和200)的整数(以厘米为单位)分别表示10个苹果到地面的高度,两个相邻的整数之间用一个空格隔开。第二行只包括一个100到120之间(包含100和120)的整数(以厘米为单位),表示陶陶把手伸直的时候能够达到的最大高度。【输出文件】 输出文件apple.out包括一行,这一行只包含一个整数,表示陶陶能够摘到的苹果的数目。 【样例输入】 100 200 150 140 129 134 167 198 200 111

110 【样例输出】 5 分析:拿到这道题,我觉得还是比较简单的。由于数据范围都不超过200,用integer完全就足够了,具体步骤如下: 1.读入 2.循环 1 to 10 3.判断,找出最优解 4.输出 【程序清单】 program apple; var i,n,s:integer; a:array[1..10] of integer; begin assign(input,'apple.in'); reset(input); for i:=1 to 10 do read(a[i]); read(n); s:=0;

noip2016普及组解题报告

买铅笔 【题目描述】 P老师需要去商店买n支铅笔作为小朋友们参加NOIP的礼物。她发现商店一共有 3种包装的铅笔,不同包装内的铅笔数量有可能不同,价格也有可能不同。为了公平起见,P老师决定只买同一种包装的铅笔。 商店不允许将铅笔的包装拆开,因此P老师可能需要购买超过n支铅笔才够给小朋友们发礼物。 现在P老师想知道,在商店每种包装的数量都足够的情况下,要买够至少n 支铅笔最少需要花费多少钱。 【输入格式】 输入的第一行包含一个正整数n,表示需要的铅笔数量。 接下来三行,每行用两个正整数描述一种包装的铅笔:其中第一个整数表示这种包装内铅笔的数量,第二个整数表示这种包装的价格。 保证所有的7个数都是不超过10000的正整数。 【输出格式】 输出一行一个整数,表示P老师最少需要花费的钱。 【样例输入】 57 2 2 50 30 30 27 【样例输出】 54

【算法分析】 水题,整除、取余。【AC代码】 var n,i,a,b,p,ans:longint; begin readln(n); ans:=maxlongint; for i:=1 to 3 do begin read(a,b); if (n mod a)<>0 then p:=(n div a +1)*b else p:=(n div a)*b; if p

回文日期 【题目描述】 在日常生活中,通过年、月、日这三个要素可以表示出一个唯一确定的日期。牛牛习惯用8位数字表示一个日期,其中,前4位代表年份,接下来2位代表月份,最后2位代表日期。显然:一个日期只有一种表示方法,而两个不同的日期的表示方法不会相同。 牛牛认为,一个日期是回文的,当且仅当表示这个日期的8位数字是回文的。现在,牛牛想知道:在他指定的两个日期之间包含这两个日期本身),有多少个真实存在的日期是回文的。 一个8位数字是回文的,当且仅当对于所有的i ( 1 <=i<= 8 )从左向右数的第i 个数字和第9-i个数字(即从右向左数的第i个数字)是相同的。 例如: ?对于2016年11月19日,用8位数字20161119表示,它不是回文的。 ?对于2010年1月2日,用8位数字20100102表示,它是回文的。 ?对于2010年10月2日,用8位数字20101002表示,它不是回文的。 每一年中都有12个月份:其中,1、3、5、7、8、10、12月每个月有31天;4、6、9、11月每个月有30天;而对于2月,闰年时有29天,平年时有28天。 一个年份是闰年当且仅当它满足下列两种情况其中的一种: 1.这个年份是4的整数倍,但不是100的整数倍; 2.这个年份是400的整数倍。 例如: ?以下几个年份都是闰年:2000、2012、2016。 ?以下几个年份是平年:1900、2011、2014。 【输入格式】 输入包括两行,每行包括一个8位数字。 第一行表示牛牛指定的起始日期。 第二行表示牛牛指定的终止日期。 保证date_i和都是真实存在的日期,且年份部分一定为4位数字,且首位数字不为0。 保证date1 —定不晚于date2。 【输出格式】 输出一行,包含一个整数,表示在date1和date2之间,有多少个日期是回文的。【样例输入】 20000101 20101231 【样例输出】 2

相关文档
最新文档