noip2018年提高组复赛解题报告

noip2018年提高组复赛解题报告
noip2018年提高组复赛解题报告

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”表示循环体结束。循环体结束时,这个循环体新建的变量也被销毁。注:本题中为了书写方便,在描述复杂度时,使用大

写英文字母“O”表示通常意义下“Θ”的概念。【输入格式】输入文件名为complexity.in。输入文件第一行一个正整数t,表示有t(t ≤10)个程序需要计算时间复杂度。每个程序我们只需抽取其中“F i x y”和“E”即可计算时间复杂度。注意:循环结构允许嵌套。接下来每个程序的第一行包含一个正整数L 和一个字符串,L 代表程序行数,字符串表示这个程序的复杂度,“O(1)”表示常数复杂度,“O(n^w)”表示复杂度为n^w,其中w 是一个小于100 的正整数(输入中不包含引号),输入保证复杂度只有O(1)和O(n^w) 两种类型。接下来L 行代表程序中循环结构中的“F i x y”或者“E”。程序行若以“F”开头,表示进入一个循环,之后有空格分离的三个字符(串)i x y,其中i 是一个小写字母(保证不为“n”),表示新建的变量名,x 和y 可能是正整数或n ,已知若为正整数则一定小于100。程序行若以“E”开头,则表示循环体结束。【输出格式】输出文件名为complexity.out。输出文件共t 行,对应输入的t 个程序,每行输出“Yes”或“No”或者“ERR”(输出中不包含引号),若程序实际复杂度与输入给出的复杂度一致则输出“Yes”,不一致则输出“No”,若程序有语法错误(其中语法错误只有: F 和E 不匹配;新建的变量与已经存在但未被销毁的变量重复两种情况),则输出“ERR”。注意:即使在程序不会执行的循环体中出现了语法错误也会编译错误,要输出“ERR”。

【输入输出样例1】complexity.in82 O(1)F i 1 1E2

O(n^1)F x 1 nE1 O(1)F x 1 n4 O(n^2)F x 5 nF

y 10 nEE4 O(n^2)F x 9 nEF y 2 nE4 O(n^1)F x 9 nF y n 4EE4 O(1)F y n 4F x 9 nEE4 O(n^2)F x 1 nF x 1

10EEcomplexity.outYesYesERRYesNoYesYesERR【数据规模与约定】对于30%的数据:不存在语法错误,数据保证小明给出的每个程序的前L/2 行一定为以 F 开头的语句,第

L/2+1 行至第L 行一定为以E 开头的语句,L,若x、y 均为整数,x 一定小于y,且只有y 有可能为n。对于50%的数据:不存在语法错误,L,且若x、y均为整数,x 一定小于y,且只有y 有可能为n。对于70%的数据:不存在语法错误,L。对于100%的数据:L。用STL stack模拟,对于用代码量堆出来的OIer来说,这就是信心倍增的大力模拟题。代码就不上了。 3. 逛公园(park.cpp/c/pas)【问题描述】策策同学特别喜欢逛公园。公园可以看成一张N个点M条边构成的有向图,且没有自环和重边。其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值,代表策策经过这条边所要花的时间。策策每天都会去逛公园,他总是从1号点进去,从N号点出来。策策喜欢新鲜的事物,他不希望有两天逛公园的路线完全一样,同时策策还是一个特别热爱学习的好孩子,他不希望每天在逛公园这件事上花费太多

的时间。如果1号点到N号点的最短路长为d,那么策策只会喜欢长度不超过d+K的路线。策策同学想知道总共有多少条满足条件的路线,你能帮帮他吗?为避免输出过大,答案对P取模。如果有无穷多条合法的路线,请输出?1。【输入格式】输入文件名为park.in。第一行包含一个整数T, 代表数据组数。接下来T组数据,对于每组数据:第一行包含四个整数N, M, K, P,每两个整数之间用一个空格隔开。接下来M行,每行三个整数ai , bi , ci,代表编号为ai, bi的点之间有一条权值为ci的有向边,每两个整数之间用一个空格隔开。【输出格式】输出文件名为park.out。输出文件包含T行,每行一个整数代表答案。【输入输出样例1】park.in25 7 2 101 2 12 4 04 5 22 3 23 4 13 5 21 5 32 2 0 101 2 02 1 0park.out3-1【数据规模与约定】对于不同的测试点,我们约定各种参数的规模不会超过如下:对于100%的数据, 1≤P≤109,1≤ai,bi≤??,0≤ci ≤1000。数据保证:至少存在一条合法的路线。最短路+拓扑排序+DP先跑最短路。发现K只有50,所以一定是要从K入手。所以考虑DP,令f[i][j]表示走到i,多走的长度是j的方案数。(多走指的是比最短路多的部分的长度)。但是发现这个DP方程是存在环的,因为最短路径图上的边以及零边都是可以同行转移的。将最短路径图上的边以及零边都拿出来跑拓扑排序,然后让这些边在转移时必须沿着拓扑序转移即可。特别地,

如果一个零环位于一条从1到n长度的路径上,则输出-1即可。#include#include#include#include#include#include#define mp(A,B) make_pair(A,B)using namespace std;const int

maxn=100010;const int maxm=200010;int

n,m,cnt,K,P,tot,ans;int

to[maxm],next[maxm],val[maxm],head[maxn],dis[maxn],vis[m axn],d[maxn],q[maxnint

to2[maxm],next2[maxm],val2[maxm],head2[maxn],dis2[maxn]; priority_queue> pq;inline int rd(){ int ret=0; char

gc=getchar(); while(gc'9') gc=getchar();

while(gc>='0'&&gc return ret;}inline void add(int a,int b,int c){ to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt;

to2[cnt]=a,val2[cnt]=c,next2[cnt]=head2[b],head2[b]=cnt++;}in line void upd(int &x,int y){ x=(x+y)%P;}void

work(){ n=rd(),m=rd(),K=rd(),P=rd(); int i,j,k,a,b,c,u; memset(head,-1,sizeof(head)),memset(head2,-1,sizeof(head2)),c nt=tot=ans=0; for(i=1;i //1

memset(vis,0,sizeof(vis)),memset(dis,0x3f,sizeof(dis)),memset( d,0,sizeof(d)); pq.push(mp(0,1)),dis[1]=0;

while(!pq.empty()) { u=pq.top().second,pq.pop(); if(vis[u]) continue; vis[u]=1;

for(i=head[u];i!=-1;i=next[i])

if(dis[to[i]]>dis[u]+val[i])dis[to[i]]=dis[u]+val[i],pq.push(mp(-d is[to[i]],to[i])); } //2

memset(dis2,0x3f,sizeof(dis2)),memset(vis,0,sizeof(vis));

pq.push(mp(0,n)),dis2[n]=0; while(!pq.empty())

{ u=pq.top().second,pq.pop(); if(vis[u]) continue; vis[u]=1;

for(i=head2[u];i!=-1;i=next2[i])

if(dis2[to2[i]]>dis2[u]+val2[i])dis2[to2[i]]=dis2[u]+val2[i],pq.p ush(mp(-dis2[to2[i]],to2[i])); } //3 for(i=1;i

for(i=1;i for(j=1;j { u=q[j];

for(i=head[u];i!=-1;i=next[i]) if(dis[u]+val[i]==dis[to[i]])

{ d[to[i]]--; if(!d[to[i]])

q[++tot]=to[i]; } } for(i=1;i

{ printf('-1\n'); return ; } //DP memset(f,0,sizeof(f)); f[0][1]=1; for(k=0;k

{ for(i=1;i

{ upd(f[k][to[j]],f[k][u]); }

for(i=1;i

{ upd(f[k+dis[i]+val[j]-dis[to[j]]][to[j]],f[k][i]);

} } for(i=0;i printf('%d\n',ans);}int

main(){ int T=rd(); while(T--) work(); return 0;} Day2 1.奶酪(cheese.cpp/c/pas)【问题描述】现有一块大奶酪,

它的高度为h,它的长度和宽度我们可以认为是无限大的,奶酪中间有许多半径相同的球形空洞。我们可以在这块奶酪中建立空间坐标系,在坐标系中,奶酪的下表面为z = 0,奶酪的上表面为z = h。现在,奶酪的下表面有一只小老鼠Jerry,它知道奶酪中所有空洞的球心所在的坐标。如果两个空洞相切或是相交,则Jerry 可以从其中一个空洞跑到另一个空洞,特别地,如果一个空洞与下表面相切或是相交,Jerry 则可以从奶酪下表面跑进空洞;如果一个空洞与上表面相切

或是相交,Jerry 则可以从空洞跑到奶酪上表面。位于奶酪下表面的Jerry 想知道,在不破坏奶酪的情况下,能否利用已有的空洞跑到奶酪的上表面去?空间内两点P(x ,y ,z )、

P(x ,y ,z )的距离公式如下:【输入格式】输入文件名为cheese.in。每个输入文件包含多组数据。输入文件的第一行,包含一个正整数T,代表该输入文件中所含的数据组数。接下来是T 组数据,每组数据的格式如下:第一行包含三个正整数n,h 和r,两个数之间以一个空格分开,分别代表奶酪中空洞的数量,奶酪的高度和空洞的半径。接下来的n 行,每行包含三个整数x、y、z,两个数之间以一个空格分开,表示空洞球心坐标为(x, y, z)。【输出格式】输出文件名为cheese.out。输出文件包含T 行,分别对应T 组数据的答案,如果在第i 组数据中,Jerry 能从下表面跑到上表面,则输出“Yes”,如果不能,则输出“No”(均不包含引号)。

【输入输出样例1】cheese.in32 4 10 0 10 0 32 5 10 0 10 0 42 5 20 0 22 0

4cheese.outYesNoYes【数据规模与约定】对于20%的数据,n = 1,1 ≤h , r ≤10,000,坐标的绝对值不超过10,000。对于40%的数据,1 ≤n ≤8,1 ≤h , r ≤10,000,坐标的绝对值不超过10,000。对于80%的数据,1 ≤n ≤1,000,1 ≤h , r ≤10,000,坐标的绝对值不超过10,000。对于100%的数据,1 ≤n ≤1,000,1 ≤h , r ≤

1,000,000,000,T ≤20,坐标的绝对值不超过

1,000,000,000。

真正的T1,并查集+高二数学常识。用并查集做,将位置相距小于等于2倍半径的归为一个集合。注意:Z位置+半径>=H 的,与1001归为一个集合。Z位置-半径的,与0归为一个集合。最后看0和1001是否在一个集合中。

#include#include#include#include#include#include#include#inc ludeusing namespace std;int t,n,h,r,x,y,z,f,fa[1002],t1,t2;struct sb{ int x; int y; int z;}a[1001];intfind(int

k){ if(fa[k]!=k) fa[k]=find(fa[k]); return

fa[k];}int main(){ cin>>t; for(int i=1;i

{ cin>>n>>h>>r; for(int i=1;i

fa[i]=i; fa[0]=0; fa[1001]=1001;

for(int j=1;j { cin>>a[j].x>>a[j].y>>a[j].z;

if(a[j].z+r>=h) { t1=find(j);

t2=find(1001); fa[t1]=t2; }

if(a[j].z-r { t1=find(j);

t2=find(0); fa[t1]=t2; }

for(int w=1;w

{ if(sqrt((a[j].x-a[w].x)*(a[j].x-a[w].x)+(a[j].y -a[w].y)*(a[j].y-a[w].y)+(a[j].z-a[w].z)*(a[j].z-a[w].z))

{ t1=find(j);

t2=find(w);

fa[t1]=t2; } } }

t1=find(0); t2=find(1001); if(t1==t2)

cout else cout } return 0;} 2.

宝藏(treasure.cpp/c/pas)【问题描述】参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了n 个深埋在地下的宝藏屋,也给出了这n 个宝藏屋之间可供开发的m 条道路和它们的长度。小明决心亲自前往挖掘所有宝藏屋中的宝藏。但是,每个宝藏屋距离地面都很远,也就是说,从地面打通一条到某个宝藏屋的道路是很困难的,而开发宝藏屋之间的道路则相对容易很多。小明的决心感动了考古挖掘的赞助商,赞助商决定免费赞助他打通一条从地面到某个宝藏屋的通道,通往哪个宝藏屋则由小明来决定。在此基础上,小明还需要考虑如何开凿宝藏屋之间的道路。已经开凿出的道路可

以任意通行不消耗代价。每开凿出一条新道路,小明就会与考古队一起挖掘出由该条道路所能到达的宝藏屋的宝藏。另外,小明不想开发无用道路,即两个已经被挖掘过的宝藏屋之间的道路无需再开发。新开发一条道路的代价是:这条道路的长度×从赞助商帮你打通的宝藏屋到这条道路起点的

宝藏屋所经过的宝藏屋的数量(包括赞助商帮你打通的宝藏

屋和这条道路起点的宝藏屋)。请你编写程序为小明选定由赞助商打通的宝藏屋和之后开凿的道路,使得工程总代价最小,并输出这个最小值。【输入格式】输入文件名为treasure.in。第一行两个用空格分离的正整数n 和m,代表宝藏屋的个数和道路数。接下来m 行,每行三个用空格分离的正整数,分别是由一条道路连接的两个宝藏屋的编号(编号为1~n),和这条道路的长度v。【输出格式】输出文件名为treasure.out。输出共一行,一个正整数,表示最小的总代价。【输入输出样例1】treasure.in4 51 2 11 3 31 4 12 3 43 4 1treasure.out4【样例输入输出2】treasure.in4 51 2 11 3 31 4 12 3 43 4 2treasure.out5【数据规模与约定】对于20%的数据:保证输入是一棵树,1≤n≤8,v≤5000 且所有的v 都相等。对于40%的数据:1≤n≤8,0≤m≤1000,v≤5000 且所有的v 都相等。对于70%的数据:1≤n≤8,0≤m≤1000,v≤5000对于100%的数据:1≤n ≤12,0≤m≤1000,v≤500000

状压DP一看n,明显是状压DP的数据范围。于是令f[i][S]表示当前与根连通的点的状态为S,并且最深的点的深度为i的最小代价。转移时,我们枚举所有不在S中的点,处理出每个点与S中的某个点连通所需要的最小代价。然后枚举这些点构成的所有集合S',用S'中所有点的代价+f[i][S]去更新f[i+1][S|S']即可。时间复杂度:O(n3n)。

#include#include#includeusing namespace std;typedef long long ll;int n,m,tot,ans; int map[110][110],dis[110][110],Log[4100];int f[15][4100],g[4100],ref[4100],v[15],p[15];inline int min(const int &a,const int &b){ return a} int

main(){ scanf('%d%d',&n,&m); register int i,j,a,b,c,x; for(i=0;i for(i=1;i

{ scanf('%d%d%d',&a,&b,&c),a--,b--;

map[a][b]=map[b][a]=min(map[a][b],c); } for(i=0;i memset(f,0x3f,sizeof(f)); for(i=0;i for(i=0;i

{ tot=0; for(a=0;a

{ v[tot]=60000000,p[tot]=1

for(j=x;j;j-=j&-j)

{ b=Log[j&-j];

v[tot]=min(v[tot],map[a][b]*(i+1)); }

tot++; } for(j=1;j

{ g[j]=g[j-(j&-j)]+v[Log[j&-j]];

ref[j]=ref[j-(j&-j)]|p[Log[j&-j]];

f[i+1][x|ref[j]]=min(f[i+1][x|ref[j]],f[i][x]+g[j]); } } ans=1 for(i=0;i printf('%d',ans); return 0;} 3.列队(phalanx.cpp/c/pas)【问题描述】Sylvia是一个热爱学习的女孩子。前段时间,Sylvia 参加了学校的军训。众所周知,军训的时候需要站方阵。Sylvia 所在的方阵中有n ×m名学生,方阵的行数为n,列数为m。为了便于管理,教官在训练开始时,按照从前到后,从左到右的顺序给方阵中的学生从1 到n ×m 编上了号码(参见后面的样例)。即:初始时,第i 行第j 列的学生的编号是(i?1)×m+j。然而在练习方阵的时候,经常会有学生因为各种各样的事情需要离队。在一天中,一共发生了q件这样的离队事件。每一次离队事件可以用数对(x,y) (1≤x≤n, 1≤y≤m)描述,表示第x 行第y

列的学生离队。在有学生离队后,队伍中出现了一个空位。为了队伍的整齐,教官会依次下达这样的两条指令:1.向左看齐。这时第一列保持不动,所有学生向左填补空缺。不难发现在这条指令之后,空位在第x 行第m列。2.向前看齐。这时第一行保持不动,所有学生向前填补空缺。不难发现在这条指令之后,空位在第n 行第m列。教官规定不能有两个或更多学生同时离队。即在前一个离队的学生归队之后,下一个学生才能离队。因此在每一个离队的学生要归队时,队伍中有且仅有第n 行第m 列一个空位,这时这个学生会

自然地填补到这个位置。因为站方阵真的很无聊,所以Sylvia 想要计算每一次离队事件中,离队的同学的编号是多少。注意:每一个同学的编号不会随着离队事件的发生而改变,在发生离队事件后方阵中同学的编号可能是乱序的。【输入格式】输入文件名为phalanx.in。输入共q+1 行。第 1 行包含3 个用空格分隔的正整数n, m, q,表示方阵大小是n 行m 列,一共发生了q 次事件。接下来q 行按照事件发生顺序描述了q 件事件。每一行是两个整数x, y,用一个空格分隔,表示这个离队事件中离队的学生当时排在第x

行第y 列。【输出格式】输出文件名为phalanx.out。按照事件输入的顺序,每一个事件输出一行一个整数,表示这个离队事件中离队学生的编号。【输入输出样例1】phalanx.in2 2 31 12 21 2phalanx.out114【数据规模与约定】数据保证每一个事件满足1≤x≤n,1≤y≤m。离线+平衡树由于操作是可逆的,所以将所有操作反过来做,将人的移动改成询问的反向移动,那么只需要维护这些询问点的移动即可,不难想到用数据结构。将操作顺序反过来,那么一次操作(x,y)可以看成:1.(n,m)的学生出队;2.第n列中,第x行及以下的所有学生下移一格;3.第x行中,第y列及右面的所有学生右移一格;4.将当前询问的学生放到(x,y)处。鉴于这些操作,可以选择平衡树,那么1操作就是单点删除,2,3操作就是区间加法,4操作就是单点加入。对每一行,以及最后一列

都开一棵SBT,维护其中的所有询问即可。并且注意:每一行y的范围是[1,m),即如果一行的最右面的元素位于最后一列,要将其从这一行删除,并加入到最后一列中。还有一点,如果(n,m)处有询问,说明那个询问与当前询问是重合的,所以记录一个类似于pre的东西,将那个询问的pre指向当前询问,并将那个询问删除。输出答案的时候直接令该询问的答案等于其pre的答案即可。#include#include#includeusing namespace std;const int maxn=300010;typedef long long

ll;struct node{ int ch[2],siz,val,org,tag;}s[maxnint

n,m,q,tot;int rx,ry[maxn];int bel[maxn],x[maxn],y[maxn];ll

ans[maxn];inline int rd(){ int ret=0; char gc=getchar(); while(gc'9') gc=getchar(); while(gc>='0'&&gc return ret;}inline void pushdown(int x){ if(s[x].tag)

{ if(s[x].ch[0])

s[s[x].ch[0]].val+=s[x].tag,s[s[x].ch[0]].tag+=s[x].tag;

if(s[x].ch[1])

s[s[x].ch[1]].val+=s[x].tag,s[s[x].ch[1]].tag+=s[x].tag;

s[x].tag=0; }}inline void pushup(int

x){ s[x].siz=s[s[x].ch[0]].siz+s[s[x].ch[1]].siz+1;}inline void rotate(int &x,int d){ int y=s[x].ch[d];

pushdown(x),pushdown(y);

s[x].ch[d]=s[y].ch[d^1],s[y].ch[d^1]=x;

pushup(x),pushup(y); x=y;}inline void maintain(int &x,int d){ if(s[s[s[x].ch[d]].ch[d]].siz>s[s[x].ch[d^1]].siz)

rotate(x,d); else

if(s[s[s[x].ch[d]].ch[d^1]].siz>s[s[x].ch[d^1]].siz)rotate(s[x].ch[ d],d^1),rotate(x,d); else return ;

maintain(s[x].ch[d],d),maintain(s[x].ch[d^1],d^1);

maintain(x,d),maintain(x,d^1);}void insert(int &x,int y,int

z){ if(!x)

{ x=++tot,s[x].siz=1,s[x].ch[0]=s[x].ch[1]=s[x].tag=0,s[ x].val=y,s[x].org=z; return ; } pushdown(x); int d=(y>s[x].val); insert(s[x].ch[d],y,z),pushup(x); maintain(x,d);}void del(int &x,int

y){ s[x].siz--,pushdown(x); if(s[y].val>s[x].val)

del(s[x].ch[1],y); else if(s[y].val else

{ if(!s[x].ch[0]||!s[x].ch[1])

{ x=s[x].ch[0]^s[x].ch[1];

return ; } int u=s[x].ch[1]; pushdown(u); while(s[u].ch[0]) u=s[u].ch[0],pushdown(u);

s[x].org=s[u].org,s[x].val=s[u].val;

del(s[x].ch[1],u); }}void updata(int x,int y){ if(!x) return ; pushdown(x); if(s[x].val>=y)

{ s[x].val++; if(s[x].ch[1])

s[s[x].ch[1]].val++,s[s[x].ch[1]].tag++;

updata(s[x].ch[0],y); } else

updata(s[x].ch[1],y);}inline int findmax(int

x){ pushdown(x); while(s[x].ch[1])

x=s[x].ch[1],pushdown(x); return x;}inline ll point(int a,int b) {return ll(a-1)*m+b;}void dfs(int x,int t){ if(!x) return ; pushdown(x); if(!t) ans[s[x].org]=point(s[x].val,m);

else ans[s[x].org]=point(t,s[x].val);

dfs(s[x].ch[0],t),dfs(s[x].ch[1],t);}int find(int x,int y){ if(!x) return 0; pushdown(x); if(y>s[x].val) return

find(s[x].ch[1],y); if(y return x;}int

main(){ n=rd(),m=rd(),q=rd(); int i; for(i=1;i

{ bel[i]=i; x[i]=rd(),y[i]=rd(); }

for(i=q;i>=1;i--) { int t=findmax(rx);

if(s[t].val==n)

{ bel[s[t].org]=i,del(rx,t); }

updata(rx,x[i]); updata(ry[x[i]],y[i]);

t=findmax(ry[x[i]]); if(s[t].val==m)

{ del(ry[x[i]],t),insert(rx,x[i],s[t].org); } if(y[i] else insert(rx,x[i],i); } dfs(rx,0);

for(i=1;i for(i=1;i return 0;}

长沙信息学竞赛

棋盘解题报告(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){

noip普及组复赛模拟试题18

1. 话说去年苹果们被陶陶摘下来后都很生气,于是就用最先进的克隆技术把陶陶克隆了好多份>.<然后把他们挂在树上,准备摘取。摘取的规则是,一个苹果只能摘一个陶陶,且只能在它所能摘到的高度以下(即是小于关系)的最高的陶陶,如果摘不到的话只能灰溜溜的走开了>.<给出苹果数目及每个苹果可以够到的高度和各个陶陶的高度,求苹果们都摘完后剩下多少个陶陶…… 【输入格式】第一行为两个数,分别为苹果的数量n和陶陶的数量m(n,m<=2000)以下的n行,分别为各个苹果能够到的最大高度。再接下来的m行,分别为各个陶陶的高度。高度均不高于300。 当然了,摘取的顺序按照输入的“苹果够到的最大高度”的顺序来摘。 【输出格式】输出仅有一个数,是剩下的陶陶的数量 【样例输入】5 5↙9↙10↙2↙3↙1↙6↙7↙8↙9↙10 【样例输出】3 2. 某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前5名学生发奖学金。期末,每个学生都有3门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学排在前面,这样,每个学生的排序是唯一确定的。 任务:先根据输入的3门课的成绩计算总分,然后按上述规则排序,最后按排名顺序输出前5名学生的学号和总分。注意,在前5名同学中,每个人的奖学金都不相同,因此,你必须严格按上述规则排序。例如,在某个正确答案中,如果前两行的输出数据(每行输出两个数:学号、总分)是:7 279 5 279 这两行数据的含义是:总分最高的两个同学的学号依次是7号、5号。这两名同学的总分都是279(总分等于输入的语文、数学、英语三科成绩之和),但学号为7的学生语文成绩更高一些。如果你的前两名的输出数据是:5 279 7 279则按输出错误处理,不能得分。【输入】输入文件scholar.in包含n+1行: 第1行为一个正整数n,表示该校参加评选的学生人数。 第2到n+1行,每行有3个用空格隔开的数字,每个数字都在0到100之间。第j行的3个数字依次表示学号为j-1的学生的语文、数学、英语的成绩。每个学生的学号按照输入顺序编号为1~n(恰好是输入数据的行号减1)。 所给的数据都是正确的,不必检验。 【输出】输出文件scholar.out共有5行,每行是两个用空格隔开的正整数, 依次表示前5名学生的学号和总分。 【输入输出样例1】 scholar.in scholar.out 6 90 67 80 87 66 91 78 89 91 88 99 77 67 89 64 78 89 98 6 265 4 264 3 258 2 244 1 237 【输入输出样例2】 scholar.in scholar.out 8 80 89 89 8 265 2 264

NOIP2008提高组复赛试题及题解

全国信息学奥林匹克联赛(NOIP2008)复赛 提高组 一、题目概览 二、提交源程序文件名 三、编译命令(不包含任何优化开关) 四、运行内存限制 注意事项: 1. 文件名(程序名和输入输出文件名)必须使用大写。 2. C/C++中函数main()的返回值类型必须是int,程序正常结束时的返回值必须是0。 3. 全国统一评测时采用的机器配置为:CPU 1.9GHz,内存512M,上述时限以此配置为准。各省在自测时可根据具体配置调整时限。

1. 笨小猴 (word.pas/c/cpp) 【问题描述】 笨小猴的词汇量很小,所以每次做英语选择题的时候都很头疼。但是他找到了一种方法,经试验证明,用这种方法去选择选项的时候选对的几率非常大! 这种方法的具体描述如下:假设maxn是单词中出现次数最多的字母的出现次数,minn 是单词中出现次数最少的字母的出现次数,如果maxn-minn是一个质数,那么笨小猴就认为这是个Lucky Word,这样的单词很可能就是正确的答案。 【输入】 输入文件word.in只有一行,是一个单词,其中只可能出现小写字母,并且长度小于100。【输出】 输出文件word.out共两行,第一行是一个字符串,假设输入的的单词是Lucky Word,那么输出“Lucky Word”,否则输出“No Answer”; 第二行是一个整数,如果输入单词是Lucky Word,输出maxn-minn的值,否则输出0。 【输入输出样例1】 【输入输出样例1解释】 单词error中出现最多的字母r出现了3次,出现次数最少的字母出现了1次,3-1=2,2是质数。 【输入输出样例2】 【输入输出样例2解释】 单词olympic中出现最多的字母i出现了2次,出现次数最少的字母出现了1次,2-1=1,1不是质数。 基本的字符串处理,细心一点应该没问题的,不过判断素数时似乎需要考虑下0和1的情况。var a:array['a'..'z']of integer; s:string; l,i,max,min,n:integer; ch:char;flag:boolean; begin assign(input,'word.in'); reset(input); assign(output,'word.out'); rewrite(output); readln(s);

信息学奥赛NOIP2012普及组解题报告

信息学奥赛NOIP2012普及组解题报告 1.质因数分解(prime.cpp/c/pas) 【问题描述】已知正整数n 是两个不同的质数的乘积,试求出较大的那个质数。【输入】输入文件名为prime.in。输入只有一行,包含一个正整数n。 【输出】输出文件名为prime.out。输出只有一行,包含一个正整数p,即较大的那个质数。 【输入输出样例】 【数据范围】对于60%的数据,6 ≤ n≤ 1000。对于100%的数据,6 ≤n ≤2*109。#include #include int main() { int n,i,k; scanf("%d",&n); for (i=2, k=sqrt(n) + 1;i 2 int x[10003][103], fjx[103];

NOIP1999普及组(复赛)

第五届全国青少年信息学(计算机)奥林匹克分区联赛复赛试题 (普及组 竞赛用时:3小时) 第一题 Cantor 表(30分) 现代数学的著名证明之一是Georg Cantor 证明了有理数是可枚举的。他是用下面这一张表来证明这一命题的: 我们以Z 字形给上表的每一项编号。第一项是1/1,然后是1/2,2/1,3/1,2/2,… 输入:整数N (1≤N ≤10000000) 输出:表中的第N 项 样例: INPUT OUTPUT N=7 1/4 第二题 回文数(30分) 若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。 例如:给定一个10进制数56,将56加56(即把56从右向左读),得到121是一个回文数。 又如:对于10进制数87: STEP1:87+78 = 165 STEP2:165+561 = 726 STEP3:726+627 = 1353 STEP4:1353+3531 = 4884 在这里的一步是指进行了一次N 进制的加法,上例最少用了4步得到回文数4884。 写一个程序,给定一个N (2<=N<=10,N=16)进制数M ,求最少经过几步可以得到回文数。如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible !” 样例: INPUT OUTPUT N = 9 M= 87 STEP=6 第三题 旅行家的预算(40分) 一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离D1、汽车油箱的容量C (以升为单位)、每升汽油能行驶的距离D2、出发点每升汽油价格P 和沿途油站数N (N 可以为零),油站i 离出发点的距离Di 、每升汽油价格Pi (i=1,2,…,N )。计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution ”。 样例: INPUT … 1/1 1/2 1/3 1/4 1/5 … 2/1 2/2 2/3 2/4 … 3/1 3/2 3/3 … 4/1 4/2 … 5/1 … …

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

NOIP2015普及组复赛试题

CCF全国信息学奥林匹克联赛(NOIP2015)复赛 普及组 (请选手务必仔细阅读本页内容) 一、题目概况 中文题目名称金币扫雷游戏求和推销员 coin mine sum salesman 英文题目与子目 录名 可执行文件名coin mine sum salesman 输入文件名coin.in mine.in sum.in salesman.in 输出文件名coin.out mine.out sum.out salesman.out 每个测试点时限1秒 测试点数目10 每个测试点分值10 附加样例文件有 结果比较方式全文比较(过滤行末空格及文末回车) 题目类型传统 运行内存上限128M 二、提交源程序文件名 对于C++语言coin.cpp mine.cpp sum.cpp salesman.cpp 对于C语言coin.c mine.c sum.c salesman.c 对于Pascal语言coin.pas mine.pas sum.pas salesman.pas 四、注意事项: 1、文件名(程序名和输入输出文件名)必须使用英文小写。 2、C/C++中函数main()的返回值类型必须是int,程序正常结束时的返回值必须是0。 3、全国统一评测时采用的机器配置为:CPU AMD Athlon(tm)II x2240processor,2.8GHz,内存4G,上述时限以此配置为准。 4、只提供Linux格式附加样例文件。 5、特别提醒:评测在当前最新公布的NOI Linux下进行,各语言的编译器版本以其为准。

1.金币 (coin.cpp/c/pas) 【问题描述】 国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去:当连续N天每天收到N枚金币后,骑士会在之后的连续N+1天里,每天收到N+1枚金币。 请计算在前K天里,骑士一共获得了多少金币。 【输入格式】 输入文件名为coin.in。 输入文件只有1行,包含一个正整数K,表示发放金币的天数。 【输出格式】 输出文件名为coin.out。 输出文件只有1行,包含一个正整数,即骑士收到的金币数。 【输入输出样例1】 coin.in coin.out 614 见选手目录下的coin/coin1.in和coin/coin1.ans。 【输入输出样例1说明】 骑士第一天收到一枚金币;第二天和第三天,每天收到两枚金币;第四、五、六天,每天收到三枚金币。因此一共收到1+2+2+3+3+3=14枚金币。 【输入输出样例2】 coin.in coin.out 100029820 见选手目录下的coin/coin2.in和coin/coin2.ans。 【数据说明】 对于100%的数据,1≤K≤10,000。

NOIP2007提高组复赛试题解题报告三

4、【问题描述】 帅帅经常更同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij据为非负整数。游戏规则如下: 1. 每次取数时须从每行各取走一个元素,共n个。m次后取完矩阵所有的元素; 2. 每次取走的各个元素只能是该元素所在行的行首或行尾; 3. 每次取数都有一个得分值,为每行取数的得分之和;每行取数的得分 = 被取走的元素值*2i,其中i表示第i次取数(从1开始编号); 4. 游戏结束总得分为m次取数得分之和。 帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分。【输入】 输入文件game.in包括n+1行; 第一行为两个用空格隔开的整数n和m。 第2~n+1行为n*m矩阵,其中每行有m个用单个空格隔开 【输出】 输出文件game.out仅包含1行,为一个整数,即输入矩阵取数后的最大的分。【输入输出样例1】 game.in game.out 2 3 82 1 2 4 3 4 2 【输入输出样例1解释】 第1次:第一行取行首元素,第二行取行尾元素,本次的氛围1*21+2*21=6 第2次:两行均取行首元素,本次得分为2*22+3*22=20 第3次:得分为3*23+4*23=56。总得分为6+20+56=82 【输入输出样例2】 game.in game.out 1 4 122 4 5 0 5 【输入输出样例3】 game.i n game.out 2 1 0 316994 96 56 54 46 86 12 23 88 80 43 16 95 18 29 30 53 88 83 64 67 【限制】 60%的数据满足:1<=n, m<=30,答案不超过1016 100%的数据满足:1<=n, m<=80,0<=aij<=1000

历年noip初赛普及组试题(完整资料).doc

【最新整理,下载后即可编辑】 历年noip普及组初赛试题汇编 芜湖县实验学校NOIP初赛复习资料

第十五届全国青少年信息学奥林匹克联赛初赛试题(2009) (普及组C++语言二小时完成) ●●全部试题答案均要求写在答卷纸上,写在试卷纸 上一律无效●● 一.单项选择题(共20题,每题1.5分,共计30分。每题有且仅有一个正确答案。) 1、关于图灵机下面的说法哪个是正确的: A)图灵机是世界上最早的电子计算机。 B)由于大量使用磁带操作,图灵机运行速度很慢。 C)图灵机是英国人图灵发明的,在二战中为破译德军的密码 发挥了重要作用。 D)图灵机只是一个理论上的计算模型。 2、关于计算机内存下面的说法哪个是正确的: A)随机存储器(RAM)的意思是当程序运行时,每次具体分 配给程序的内存位置是随机而不确定的。 B)1MB内存通常是指1024*1024字节大小的内存。 C)计算机内存严格说来包括主存(memory)、高速缓存(cache) 和寄存器(register)三个部分。 D)一般内存中的数据即使在断电的情况下也能保留2个小时 以上。 3、关于BIOS下面说法哪个是正确的: A)BIOS是计算机基本输入输出系统软件的简称。 B)BIOS里包含了键盘、鼠标、声卡、显卡、打印机等常用输 入输出设备的驱动程序。 C)BIOS一般由操作系统厂商来开发完成。

D)BIOS能提供各种文件拷贝、复制、删除以及目录维护等文 件管理功能。 4、关于CPU下面哪个说法是正确的: A)CPU全称为中央处理器(或中央处理单元)。 B)CPU可以直接运行汇编语言。 C)同样主频下,32位的CPU比16位的CPU运行速度快一倍。 D)CPU最早是由Intel公司发明的。 5、关于ASCII,下面哪个说法是正确的: A)ASCII码就是键盘上所有键的唯一编码。 B)一个ASCII码使用一个字节的内存空间就能够存放。 C)最新扩展的ASCII编码方案包含了汉字和其他欧洲语言的 编码。 D)ASCII码是英国人主持制定并推广使用的。 6、下列软件中不是计算机操作系统的是: A) Windows B) Linux C) OS/2 D) WPS 7、关于互联网,下面的说法哪一个是正确的: A)新一代互联网使用的IPv6标准是IPv5标准的升级与补充。 B)互联网的入网主机如果有了域名就不再需要IP地址。 C)互联网的基础协议为TCP/IP协议。 D)互联网上所有可下载的软件及数据资源都是可以合法免 费使用的。 8、关于HTML下面哪种说法是正确的: A)HTML实现了文本、图形、声音乃至视频信息的统一编码。 B)HTML全称为超文本标记语言。 C)网上广泛使用的Flash动画都是由HTML编写的。 D)HTML也是一种高级程序设计语言。

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”表示循环体结束。循环体结束时,这个循环体新建的变量也被销毁。注:本题中为了书写方便,在

NOIP普及组复赛解题分析报告

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个字符,描述整个雷区。用’*’表示地雷格,用周围的地雷个数表示非地雷格。相邻字符之间无分隔符。 【数据说明】

NOIP普及组复赛试题源程序

N O I P2011普及组复赛 1.数字反转(c/pas) 【问题描述】 给定一个整数,请将该数各个位上数字反转得到一个新数。新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零。(参见样例2) 【输入】 输入文件名为。 输入共一行,一个整数N。 【输出】 输出文件名为。 输出共1行,一个整数,表示反转后的新数。 -1,000,000,000≤N≤1,000,000,000。 【解题】这道题非常简单,可以读字符串处理,也可以读数字来处理,只不过要注意符号问题(以及-0,但测试数据没出)。 【法一】字符串处理 Var i,l,k:integer; s:string; p:boolean; begin assign(input, ''); reset(input); assign(output, ''); rewrite(output); readln(s); l:=length(s); k:=1; if s[1]='-' then begin write('-'); k:=2; end; p:=true;; for i:=l downto k do begin if(p)and((s[i]='0')) then continue else begin write(s[i]); p:=false;; end; end; close(input); close(output); end. 【法二】数字处理 Var f:integer; n,ans:longint; begin assign(input, ''); reset(input);

信息学奥赛普及组1-18届问题求解题解析

历届“问题求解”解析(2013竞赛辅导) 问题求解是信息学竞赛初赛中常见题型,它共两题,每题5分,共10分,十六届增加了比重,有三题,占15分。诸如寻找假币、博弈原理、抽屉原理、容斥问题、排列组合、逻辑推理、递推关系等问题出现在问题求解中。(相关问题的具体讲解根据需要考虑发讲义) 第一届(逻辑推理问题) 1. 有标号为A 、B 、C 、D 和1、2、3、4的8个球,每两个球装一盒,分装4盒。标号为字母的球与标号 为数字的球有着某种一一对应的关系(称为匹配),并已知如下条件: ① 匹配的两个球不能在一个盒子内。 ② 2号匹配的球与1号球在一个盒子里。 ③ A 号和2号球在一个盒子里。 ④ B 匹配的球和C 号球在一个盒子里。 ⑤ 3号匹配的球与A 号匹配的球在一个盒子里。 ⑥ 4号是A 或B 号球的匹配球。 ⑦ D 号与1号或2号球匹配。 请写出这四对球匹配的情况。 第四届(递推、树、图) 1. 已知一个数列U 1,U 2,U 3,…,U N ,… 往往可以找到一个最小的K 值和K 个数a 1,a 2,…,a n 使得数列从某项开始都满足: U N+K =a 1U N+K-1+a 2U N+K-2+……+a k U N (A) 例如对斐波拉契数列1,1,2,3,5,…可以发现:当K=2,a 1 =1,a 2 =1时,从第3项起(即N>=1) 都满足U n+2 =U n+1+U n 。试对数列13,23,33,…,n 3,…求K 和a 1,a 2, …,a K 使得(A )式成立。 当K= 4,a 1,a 2,…,a k 为a 1=4, a 2=6, a 3=4,a 4=-1对数列132333,…,n 3,…(A )成立。 2.给出一棵二叉树的中序遍历:DBGEACHFI 与后序遍历:DGEBHIFCA 画出此二叉树。 3.用邻接矩阵表示下面的无向图: 表示该无向图的邻接矩阵为 0 1 0 0 0 0 0 1 0 1 1 0 0 0 0 1 0 1 0 0 0 0 1 1 0 1 1 1 0 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0 1 1 1 0 第五届(递推) 将Ln 定义为求在一个平面中用n 条直线所能确定的最大区域数目。例如:当n=1时,L1=2,进一步考虑,用n 条折成角的直线(角度任意),放在平面上,能确定的最大区域数目Zn 是多少?例如:当n=1时,Z1=2(如下图所示) 当给出n 后,请写出以下的表达式:Ln = ______________ 2、Zn = _______________ 答案为:Ln=n(n+1)/2+1(n ≥0) Zn=L2n-2n=2n2-n+1 解析:本题实质是求直线或折线将一个平面分成的最大区域数,从两个方面考虑: (1)求在一个平面中用n 条直线所能确定的最大区域数; n=1,L1=2, F(1)=2 n=2,L2=4, F(2)=F(1)+2 n=3,L3=7, F(3)=F(2)+3 n=4,L4=11, F(4)=F(3)+4 …… 所以, F(n)=F(n-1)+n 把上面的n 个等式左右相加,化简得出:F (n )=2+2+3+4+……+n 即:L (n )=n*(n+1)/2+1

NOIP复赛普及组测试试题

NOIP复赛普及组试题

————————————————————————————————作者:————————————————————————————————日期:

CCF全国信息学奥林匹克联赛(NOIP2013)复赛 普及组 (请选手务必仔细阅读本页内容) 一.题目概况 中文题目名称计数问题表达 式求 值 小朋友的 数字 车站分 级 英文 题目 与子 目录 名 count expr number level 可执行 文件名 count expr number level 输入文 件名 count.in expr.in number.in level.in 输出文count.out expr.out n umber.out level.out

件名 每个 测试 点时 限 1 秒 1 秒 1 秒 1 秒 测试点 数目 10 10 10 10 每个 测试 点分 值 10 10 10 10 附加样 例文件 有有有有 结果比较方式全文比较(过滤行末空格及文末回车) 题目类 型 传统传统传统传统

运行内 存上限 128M 128M 128M 128M 二.提交源程序文件名 对于 C++语 言 count.cpp expr.cpp number.cpp level.cpp 对于 C 语 言 count.c expr.c number.c level.c 对于 pascal 语言 count.pas expr.pas number.pas level.pas 三.编译命令(不包含任何优化开关) 对于C++语言 g++ -o count count.cpp -lm g++ -o expr expr.cpp –lm g++ -o number number.cpp -lm g++ -o level level.cpp -lm 对于C 语言gcc -o count gcc -o expr gcc-o number gcc -o level

NOIP普及组复赛试题

CCF全国信息学奥林匹克联赛(NOIP2017)复赛 普及组 (请选手务必仔细阅读本页内容) 注意事项: 1、文件名(程序名和输入输出文件名)必须使用英文小写。 2、C/C++中函数main()的返回值类型必须是int,程序正常结束时的返回值必须是0。 3、全国统一评测时采用的机器配置为:CPU AMD Athlon(tm) II x2 240 processor,2.8GHz, 内存4G,上述时限以此配置为准。 4、只提供Linux格式附加样例文件。 5、提交的程序代码文件的放置位置请参照各省的具体要求。 6、特别提醒:评测在当前最新公布的NOI Linux下进行,各语言的编译器版本以其为准。

1. 成绩 (score.cpp/c/pas) 【问题描述】 牛牛最近学习了C++入门课程,这门课程的总成绩计算方法是: 总成绩=作业成绩×20%+小测成绩×30%+期末考试成绩×50% 牛牛想知道,这门课程自己最终能得到多少分。 【输入格式】 输入文件名为score.in。 输入文件只有1行,包含三个非负整数A、B、C,分别表示牛牛的作业成绩、小测成绩和期末考试成绩。相邻两个数之间用一个空格隔开,三项成绩满分都是100分。 【输出格式】 输出文件名为score.out。 输出文件只有1行,包含一个整数,即牛牛这门课程的总成绩,满分也是100分。 见选手目录下的score/score1.in和score/score1.ans。 【输入输出样例1说明】 牛牛的作业成绩是100分,小测成绩是100分,期末考试成绩是80分,总成绩是100×20%+100×30%+80×50%=20+30+40=90。 【输入输出样例2说明】 牛牛的作业成绩是60分,小测成绩是90分,期末考试成绩是80分,总成绩是60×20%+90×30%+80×50%=12+27+40=79。 【数据说明】 对于30%的数据,A=B=0。 对于另外30%的数据,A=B=100。 对于100%的数据,0≤A、B、C≤100且A、B、C都是10的整数倍。

相关文档
最新文档