NOIP2011提高组复赛试题与简解(转载)
- 格式:doc
- 大小:308.50 KB
- 文档页数:13
全国信息学奥林匹克联赛(NOIP2011)复赛提高组模拟模拟试题试题试题(一试)(一试)(请选手务必仔细阅读本页内容)一.题目概况中文题目名称订正作业怪兽对对碰采油区域英文题目与子目录名correct monster oil 可执行文件名correct monster oil 输入文件correct.in monster.in oil.in 输出文件correct.out monster.out oil.out 每个测试点时限1秒1秒 1.5秒测试点数目101010每个测试点分值101010附加样例文件有有有结果比较方式全文比较(过滤行末空格及文末回车)题目类型传统传统传统二.提交源程序文件名三.运行内存限制对于pascal 语言correct.pas ball.pas .pas 对于C 语言correct.c ball.c .c 对于C++语言correct.cppball.cpp.cpp内存上限128M128M128M1.订正作业(correctcorrect.pas/c/cpp).pas/c/cpp)【问题描述】丁丁是个富有爱心的哥哥。
他上小学的弟弟小丁丁刚刚学习了四则运算,并做了作业。
现在小丁丁把自己的作业给了丁丁,请他帮忙检查订正一下作业。
作业题都是一些含有括号的四则运算等式。
丁丁发现他的弟弟对于括号的使用不太明白,在作业中写了不少多余的括号。
现在丁丁的任务是找出这些多余的括号,并把他们擦去。
但是为了尽可能避免自己的笔迹出现,只能改动括号。
要求保持原表达式中变量和运。
另外,由于弟弟在上小学,不必考虑“+”“-”作为正负号的情况。
即输入的表达式中”“-”用于“+X”(正数)或是“-X”(负数)的情况。
也不必考虑式子中有超过20输入文件名为correct.in。
第一行为一个正整数n,表示作业题的数量。
接下来的n行,每行有n个含括号的等式,表示待丁丁订正的作业题。
【输出】输出文件名为correct.out。
NOIP2011初赛提高组答案详细解析一、单项选择二、多项选择5. C是显然要选的,本题因为有300+400=700的情况,所以B也是可以的。
7.首先要知道逆序对的定义:序列A[1..n]里,对于i<j的A[i]>A[j],则称A[i]与A[j]为一对逆序对。
将给定的序列中所有逆序对列出来,统计其中数字只出现过3次的。
8.阶码肯定是要选的,D较长的尾数也是浮点数的一个特点,它只是保正了浮点数一定的精度,并不是它可以表示很大或者很小的数的原因。
9.本题描述有点含糊,它的本意可能是在计算S到B点的距离时出现有值。
三、问题求解1.9平面图中点数n与边数m之间的关系是:m<=3n-6,当n=5时,m的最大值为9。
2. 4求出给定的长度为n的字符串的最长上升序列的长度m,最小的操作次数为n-m。
四、阅读程序题1. 3先是统计出各个数字出现的次数存放在a数组里,然后I从1开始累加a[i],直到总数超过n的一半,最后输出i。
2.1 2 5 13 34斐波那契数列间隔输出3.150求遍历图中各个点所有边长的和的最大值。
本题4个点,求3条不同边的边长和的最大值。
4.57344 (213*7)本题稍有些难度,观察m*n的0-1矩阵,可以看出m=2n,此矩阵其实就是所有7位的二进制数。
每一列中有2n-1个1和个0,在一列里每个1都有2^(n-1)个0与它不同,同样每个0也有2^(n-1)个1与它不同,即每列的结果为22n-2*2=22n-1,n列的结果为n*22n-1,所以本题的结果为213*7.此题也可以从递推的角度来求解:f(n)=4n/(n-1)*f(n-1) (因为列增加1时行变为原来两倍,01的个数也对应为原来2倍)f(1)=2由此递推式子也可以得到通项公式:f(n)=n*22n-1。
再分析此题,发现就是从0开始由小到大每次增加1构造出所有n位二进制数,如果将低位写在右边更符合平常习惯,更易看出结果。
第十七届全国青少年信息学奥林匹克联赛初赛试题(提高组 Pascal语言两小时完成)一、单项选择题(共20题,每题1.5分。
共计30分。
每题有且仅有一个正确选项。
)1.在二进制下, +()= 。
A.1011 B.1101 C.1010 D.11112.字符“A”的ASCII码为十六进制41,则字符“Z”的ASCII码为十六进制的()。
A.66 B.5A C.50 D.视具体的计算机而定3.右图是一棵二叉树,它的先序遍历是()。
A.ABDEFC B.DBEFAC C.DFEBCA D.ABCDEF4.寄存器是()的重要组成部分。
A.硬盘B.高速缓存C.内存D.中央处理器(CPU)5.广度优先搜索时,需要用到的数据结构是()。
A.链表B.队列C.栈D.散列表6.在使用高级语言编写程序时,一般提到的“空间复杂度”中的“空间”是指()。
A.程序运行时理论上所占的内存空间B.程序运行时理论上所占的数组空间C.程序运行时理论上所占的硬盘空间D.程序源文件理论上所占的硬盘空间7.应用快速排序的分治思想,可以实现一个求第K大数的程序。
假定不考虑极端的最坏情况,理论上可以实现的最低的算法时间复杂度为()。
A.O(n2)B.O(n log n)C.O(n) D.O(1)8.为解决Web应用中的不兼容问题,保障信息的顺利流通,()制定了一系列标准,涉及HTML、XML、CSS等,并建议开发者遵循。
A.微软 B.美国计算机协会(ACM) C.联台国教科文组织D.万维网联盟(W3C)9.体育课的铃声响了,同学们都陆续地奔向操场,按老师的要求从高到矮站成一排。
每个同学按顺序来到操场时,都从排尾走向排头,找到第一个比自己高的同学,并站在他的后面。
这种站队的方法类似于()算法。
A.快速排序B.插入排序C.冒泡排序D.归并排序10.1956年()授予肖克利(William Shockley)、巴丁(John Bardeen)和布拉顿(Walter Brattain),以表彰他们对半导体的研究和晶体管效应的发现。
NOIP2011复赛题解noip2011普及组解题报告NOIP2011普及组解题报告——ahbbzeq 2011.11.25 转载请注明来源一、数字反转没得满分只能说明一个问题,你的程序写的太少了。
program reverse;vars:string;i,sta:longint;beginassign(input,'reverse.in');reset(input);assign(output,'reverse.out');rewrite(output);readln(i);str(i,s);sta:=1;if s[1]='-' thenbeginwrite('-');sta:=2;end;i:=length(s);while (s[i]='0') and (i>sta) dodec(i);while (i>=sta) dobeginwrite(s[i]);dec(i);end;close(input);close(output);end.二、统计单词个数考你的基本功,和对程序的理解,尤其是细节上的优化。
直接在文章中选出单词,与给定单词长度一致时才比较,函数传参数时也不要传字符串(会很慢的,具体慢多少没试)。
program stat;vars,p:ansistring;i,j,first,num,len,c,k:longint;function cmp(x:longint):boolean;vari:longint;beginfor i:= 1 to c doif s[i]<> p[x+i-1] then exit(false);exit(true);end;beginassign(input,'stat.in');reset(input);assign(output,'stat.out');rewrite(output);readln(s);readln(p);s:=upcase(s);p:=upcase(p);c:=length(s); len:=length(p);i:=1; num:=0; first:=-1;while (s[i]=' ')and (i<=len) do inc(i);while (i<=len) dobeginj:=i+1;while (p[j]<>' ') and (j<=len) doinc(j);if (j-i = c) and cmp(i) thenbeginif first=-1 then first:=i;inc(num);end;i:=j; while (p[i]=' ') and (i<=len) do inc(i); end;if first=-1 thenwriteln(-1)else writeln(num,' ',first-1);close(input);close(output);end.三、瑞士轮实践证明,如果单纯的排序r次,必然结果是超时。
Noip 2011 提高组(Day 1)解题报告及程序一、铺地毯正着扫一遍判断每个矩形是否覆盖询问的点,覆盖则更新结果或者倒着扫一遍,找到第一个覆盖询问点的矩形,输出即可,时间复杂度O(n)Procedure:#include <cstdio>#define MaxLength 10000inline int Getint(){char c = getchar();while (c<'0' || c>'9') c = getchar();int ret = 0;while (c>='0' && c<='9'){ret = ret*10 + (c-'0');c = getchar();}return ret;}int sx[MaxLength+5], sy[MaxLength+5], ex[MaxLength+5], ey[MaxLength+5], n; void Init(){n = Getint();for (int i=1; i<=n; i++){sx[i] = Getint(), sy[i] = Getint(), ex[i] = Getint(), ey[i] = Getint();ex[i] += sx[i], ey[i] += sy[i];}return ;}int x0, y0, ans = -1;void Solve(){x0 = Getint(), y0 = Getint();for (int i=n; i;i--)if(x0>=sx[i] && x0<=ex[i] && y0>=sy[i] && y0<=ey[i]){ans = i;break;}printf("%d", ans);return ;}int main(){Init();Solve();getchar(); getchar();return 0;}二、选择客栈f [i][j]表示前i个客栈以第j种颜色的方案数,先以客栈划分第一阶段,以颜色划分第二阶段,如果颜色相同的客栈,则以前一客栈相同颜色的方案数+1,否则同其一样;计算答案时记一下前一个比最高消费限制低的客栈编号pos[i],路径压缩,时间复杂度O(nm)Procedure:#include <cstdio>#define MaxNode 200000#define MaxType 50inline int Getint(){char c = getchar();while (c<'0' || c>'9') c = getchar();int ret = 0;while (c>='0' && c<='9'){ret = ret*10 + (c-'0');c = getchar();}return ret;}int color[MaxNode+5], price[MaxNode+5], n, m, low;void Init(){n = Getint(), m = Getint(), low = Getint();for (int i=1; i<=n; i++) color[i] = Getint(), price[i] = Getint();return ;}int f[MaxNode+5][MaxType+5], pos[MaxNode+5], ans = 0;void Dp(){for (int i=1; i<=n; i++)for (int j=0; j<m; j++)if (color[i]==j) f[i][j] = f[i-1][j]+1;else f[i][j] = f[i-1][j];for (int i=1; i<=n; i++)if (price[i]<=low){pos[i] = i;ans += f[i-1][color[i]];}else{pos[i] = pos[i-1];ans += f[pos[i]][color[i]];}printf("%d", ans);return ;}int main(){Init();Dp();getchar(); getchar();return 0;}三、Mayan纯暴力DFS,加可行性剪枝,如同一种颜色小于3块无法消除,同一颜色交换无意义,下落无法完成左右移动,再加模拟其过程时间复杂度O( n^(?) )Procedure:#include <cstdio>#include <memory>inline int Getint(){char c = getchar();while (c<'0' || c>'9') c = getchar();int ret = 0;while (c>='0' && c<='9'){ret = ret*10 + (c-'0');c = getchar();}return ret;}inline void Swap(int &a, int &b){int temp = a; a = b; b = temp;return ;}int map[10][10], point[10], color[15], n, type = 0;void Init(){n = Getint();for (int i=0; i<5; i++){map[i][0] = Getint();if (type<map[i][point[i]]) type = map[i][point[i]];color[ map[i][point[i]] ]++;while (map[i][point[i]]){map[i][++point[i]] = Getint();if (type<map[i][point[i]]) type = map[i][point[i]];color[ map[i][point[i]] ]++;}point[i]--;}return ;}bool Fall(int k){int top = -1;for (int i=0; i<=point[k]; i++)if (map[k][i]) map[k][++top] = map[k][i];if (top!=point[k]){for (int i=top+1; i<=point[k]; i++) map[k][i] = 0;point[k] = top;return true;}return false;}bool Check_Fall(){bool flag = false;for (int i=0; i<5; i++)if (Fall(i)) flag = true;return flag;}bool sign[10][10];void Clear(){int pmax = 0;for (int i=0; i<5; i++)if (point[i]>pmax) pmax = point[i];for (int i=0; i<5; i++)if (point[i]>=2){int k = point[i], j = k-1;for (; j>=0; j--)if (map[i][j]!=map[i][k]){if (k-j>=3)for (; k>j; k--) sign[i][k] = true;else k = j;}if (k-j>=3)for (; k>j; k--) sign[i][k] = true;}for (int i=0; i<=pmax; i++){int k = 0, j = 1;for (; j<5; j++)if (map[j][i]!=map[k][i]){if (j-k>=3)for (; k<j; k++) sign[k][i] = true;else k = j;}if (j-k>=3)for (; k<j; k++) sign[k][i] = true;}for (int i=0; i<5; i++)for (int j=pmax; j>=0; j--)if (sign[i][j]){sign[i][j] = false;color[map[i][j]]--;map[i][j] = 0;}return ;}void Solve(int x, int y){Fall(x), Fall(y);Clear();while (Check_Fall()) Clear();return ;}bool Check_Point(){for (int i=0; i<5; i++)if (point[i]>=0)return false;return true;}bool Check_Color(){for (int i=1; i<=type; i++)if (color[i]==1 || color[i]==2) return false;return true;}struct Ac{int m[10][10], p[10], c[15];}a[10];inline void Copy(int k){memcpy(a[k].m, map, sizeof(map));memcpy(a[k].p, point, sizeof(point));memcpy(a[k].c, color, sizeof(color));return ;}inline void Turn_Copy(int k){memcpy(map, a[k].m, sizeof(a[k].m));memcpy(point, a[k].p, sizeof(a[k].p));memcpy(color, a[k].c, sizeof(a[k].c));return ;}int ans[10][10];bool Dfs(int deep){if (!Check_Color()) return false;Copy(deep);for (int i=0; i<5; i++)for (int j=0; j<=point[i]; j++){ans[deep][0] = i, ans[deep][1] = j;if (i<4){ans[deep][2] = 1;Swap(map[i][j], map[i+1][j]);if (point[i+1]<j) point[i+1] = j;Solve(i, i+1);if (deep==n && Check_Point()) return true;if (deep<n && Dfs(deep+1)) return true;Turn_Copy(deep);}if (i && point[i-1]<j){ans[deep][2] = -1;Swap(map[i][j], map[i-1][j]);point[i-1] = j;Solve(i, i-1);if (deep==n && Check_Point()) return true;if (deep<n && Dfs(deep+1)) return true;Turn_Copy(deep);}}return false;}int main(){Init();if (!Dfs(1)) printf("-1");elsefor (int i=1; i<=n; i++)printf("%d %d %d\n", ans[i][0], ans[i][1], ans[i][2]);getchar(); getchar();return 0;}Noip 2011 提高组(Day 2)解题报告及程序一、计算系数二项式定理,杨辉三角,注意Mod就可以了,时间复杂度O(k^2)Procedure:#include <cstdio>#define MaxNode 1000#define Mod 10007int f[MaxNode+5][MaxNode+5], a, b, k, n, m;void Init(){scanf("%d %d %d %d %d", &a, &b, &k, &n, &m);a %= Mod,b %= Mod, k++;for (int i=1; i<=k; i++) f[i][1] = f[i][i] = 1;for (int i=2; i<=k; i++)for (int j=2; j<i; j++)f[i][j] = (f[i-1][j-1] + f[i-1][j])%Mod;return ;}void Solve(){int x = k, y = k-n;for (int i=1; i<=n; i++) f[x][y] = (f[x][y] * a)%Mod;for (int j=1; j<=m; j++) f[x][y] = (f[x][y] * b)%Mod;printf("%d", f[x][y]%Mod);return ;}int main(){Init();Solve();getchar(); getchar();return 0;}二、聪明的质检员由观察得随着参数W的上升检验值temp会减小,据函数Abs(标准值-temp)有最小值,故可二分查找得出答案其中每次调整参数W时扫描一次矿石中大于W的,num[]表示其数量前缀和,val[]表示其价值前缀和,故可在一个区间的检验值计算中以O(1)的时间得出答案时间复杂度O(log(w)*(n+m))Procedure:#include <cstdio>#define MaxNode 200000#define INF ((0x7fffffffffffffffll)>>1)inline int Getint(){char c = getchar();while (c<'0' || c>'9') c = getchar();int ret = 0;while (c>='0' && c<='9'){ret = ret*10 + (c-'0');c = getchar();}return ret;}long long Abs(long long a){if (a>0) return a;return -a;}int w[MaxNode+5], val[MaxNode+5], l[MaxNode+5], r[MaxNode+5], n, m, lw, rw; long long standard;void Init(){n = Getint(), m = Getint(), scanf("%I64d", &standard);for (int i=1; i<=n; i++){w[i] = Getint(), val[i] = Getint();if (rw<w[i]) rw = w[i]+1;}for (int i=1; i<=m; i++) l[i] = Getint(), r[i] = Getint();return ;}int num[MaxNode+5];long long sum[MaxNode+5];long long Calc(int left, int right){return (sum[right]-sum[left]) * (num[right]-num[left]);}long long Sieve(int Limit){long long ret = 0;sum[0] = num[0] = 0;for (int i=1; i<=n; i++){num[i] = num[i-1];sum[i] = sum[i-1];if (w[i]>=Limit){num[i]++;sum[i] += val[i];}}for (int i=1; i<=m; i++) ret += Calc(l[i]-1, r[i]);return ret;}long long ans = INF;void Binary_Search()while (lw<rw){int mid = (lw+rw)>>1;long long temp = Sieve(mid);long long value = Abs(standard - temp);if (temp<standard) rw = mid;else lw = mid+1;if (ans>value) ans = value;}printf("%I64d", ans);return ;}int main(){Init();Binary_Search();getchar(); getchar();return 0;}三、观光公交贪心令t[i]表示当前到达第i个站的时间,sumoff[i]表示目的地为i的乘客数,arrtime[i]表示第i个乘客到站等车的时刻题目给定加速器的作用就是可以把某个t[i]减去1并把与其相关联的t[i]全部减小1。
全国信息学奥林匹克联赛(NOIP2011)复赛提高组day2 全国信息学奥林匹克联赛(NOIP2011)复赛提高组 day2(请选手务必仔细阅读本页内容)一.题目概况注意事项:1、文件名(程序名和输入输出文件名)必须使用英文小写。
2、C/C++中函数main()的返回值类型必须是int,程序正常结束时的返回值必须是0。
3、全国统一评测时采用的机器配置为:CPU P4 3.0GHz,内存1G,上述时限以此配置为准。
4、特别提醒:评测在NOI Linux 下进行。
全国信息学奥林匹克联赛(NOIP2011)复赛提高组day2【问题描述】1.计算系数(factor.cpp/c/pas)给定一个多项式(ax + by)k ,请求出多项式展开后x n y m 项的系数。
【输入】输入文件名为factor.in。
共一行,包含5 个整数,分别为a,b,k,n,m,每两个整数之间用一个空格隔开。
【输出】输出文件名为factor.out。
输出共1 行,包含一个整数,表示所求的系数,这个系数可能很大,输出对10007 取模后的结果。
【输入输出样例】对于30%的数据,有0≤k≤10;对于50%的数据,有a = 1,b = 1;对于100%的数据,有0≤k≤1,000,0≤n, m≤k,且n + m = k,0≤a,b≤1,000,000。
【问题描述】2.聪明的质监员(qc.cpp/c/pas)小T 是一名质量监督员,最近负责检验一批矿产的质量。
这批矿产共有n 个矿石,从1 到n 逐一编号,每个矿石都有自己的重量w i 以及价值v i。
检验矿产的流程是:1、给定m 个区间[L i,R i];2、选出一个参数W;3、对于一个区间[L i,R i],计算矿石在这个区间上的检验值Y i :Yi=∑1* ∑v j ,j ∈[L i , R i ] 且w j ≥W ,j 是矿石编号j jm这批矿产的检验结果Y 为各个区间的检验值之和。
NOIP 2011复赛练习卷(一)1、最优贸易(trade.pas/c/cpp)【问题描述】C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市。
任意两个城市之间最多只有一条道路直接相连。
这m 条道路中有一部分为单向通行的道路,一部分为双向通行的道路,双向通行的道路在统计条数时也计为 1 条。
C 国幅员辽阔,各地的资源分布情况各不相同,这就导致了同一种商品在不同城市的价格不一定相同。
但是,同一种商品在同一个城市的买入价和卖出价始终是相同的。
商人阿龙来到 C 国旅游。
当他得知同一种商品在不同城市的价格可能会不同这一信息之后,便决定在旅游的同时,利用商品在不同城市中的差价赚回一点旅费。
设C国n个城市的标号从1~ n,阿龙决定从1号城市出发,并最终在n号城市结束自己的旅行。
在旅游的过程中,任何城市可以重复经过多次,但不要求经过所有n个城市。
阿龙通过这样的贸易方式赚取旅费:他会选择一个经过的城市买入他最喜欢的商品——水晶球,并在之后经过的另一个城市卖出这个水晶球,用赚取的差价当做旅费。
由于阿龙主要是来 C 国旅游,他决定这个贸易只进行最多一次,当然,在赚不到差价的情况下他就无需进行贸易。
假设C国有5个大城市,城市的编号和道路连接情况如下图,单向箭头表示这条道路为单向通行,双向箭头表示这条道路为双向通行。
假设 1~n 号城市的水晶球价格分别为 4,3,5,6,1。
阿龙可以选择如下一条线路:1->2->3->5,并在 2 号城市以 3 的价格买入水晶球,在 3号城市以 5 的价格卖出水晶球,赚取的旅费数为 2。
阿龙也可以选择如下一条线路 1->4->5->4->5,并在第 1 次到达 5 号城市时以1 的价格买入水晶球,在第2 次到达 4 号城市时,以 6 的价格卖出水晶球,赚取的旅费数为 5。
现在给出 n 个城市的水晶球价格、m 条道路的信息(每条道路所连接的两个城市的编号以及该条道路的通行情况)),请你告诉阿龙,他最多能赚取多少旅费。
第十七届NOIP2011 提高组初赛试题+答案+解析(pascal)一、单项选择题(共10题,每题1.5分,共15分,每题有且仅有一个正确选项。
)1. 在二进制下,1011010+()=1100111。
A.1011B.1101C.1010D.1111答案:B解析:简单的二进制运算,炮灰都会。
2. 字符“A”的ASCII码为十六进制41,则字符“Z”的ASCII码为十六进制的()。
A.66 B.5A C.50 D.视具体的计算机而定答案:B解析:每年必考进制转换题。
背得ASCII码的可以直接算出Z的码然后转回16进制。
像我不背得的就把十六进制的41转回十进制,4*16+1=65,然后+25得90,再转成16进制得5A。
3. 右图是一棵二叉树,它的先序遍历是()。
(我就不画图了= =带鱼语口述一下:根是A,左右子树分别为B和C,B的左右子树分别为D和E,E的右子树为F)A.ABDEFC B.DBEFAC C.DFEBCA D.ABCDEF答案:A解析:每年必考树的遍历题。
先序遍历就是先根遍历,就是先根,再左右子树的遍历。
然后就ABDEFC出来了。
从这个解析可以看出这个解析是新手向的解析-。
-4. 寄存器是()的重要组成部分。
A. 硬盘B. 高速缓存C. 内存D. 中央处理器(CPU)答案:D解析:每年必考硬件知识题。
寄存器在CPU里。
5. 广度优先搜索时,需要用到的数据结构是()。
A. 链表B. 队列C. 栈D. 散列表答案:B解析:数据结构题。
广搜需要存每一层的一大堆东西,继续向下一层搜时需要用到,所以要用存取方便的队列。
链表取数不便,栈是深搜用的,散列表就是hash表,和宽搜没啥必然联系。
6. 在使用高级语言编写程序时,一般提到的“空间复杂度”中的“空间”是指()A. 程序运行时理论上所占的内存空间B. 程序运行时理论上所占的数组空间C. 程序运行时理论上所占的硬盘空间D. 程序源文件理论上所占的硬盘空间答案:A解析:常识题。
NOIP2011提高组题解杭州外国语学校陈立杰November13,2011Contents1Day I21.1carpet (2)1.2hotel (2)1.3manya (2)2Day II32.1factor (3)2.2qc (3)2.3bus (3)1Day I1.1carpet由于只需要询问一个点,我们只需要从头到尾扫描一遍,记录最后一个覆盖该点的矩形即可。
1.2hotel对于50%的数据,我们可以预处理出每两个点之间最小的咖啡屋价格minCost ij,然后n2枚举判断即可。
首先我们可以对题目进行一个转化,令c i在cost i>p时等于1,否则等于0,那么题目实际上就等价于求出颜色一样,之间有一个c是0的咖啡屋对数。
那么可以倒过来,来考虑计算颜色一样,之间的c全是1的对数,说白了这时这两个咖啡屋必须都位于一个c全是1的连续块中。
我们可以扫描得到每个c全是1的连续快,对一个长度为L的块,显然可以在O(L)的时间算出结果。
那么总时间复杂度就是O(N)1.3manya这是一道搜索题。
首先可以注意到,一个块往左交换,跟它左边的块往右交换是等价的,而此时后者者字典序更优所以不用考虑前者,那么一次的决策最多4∗7=28个,n=51/285≈1.7∗107。
同时可以考虑优化,先是可行性剪枝,如果有一种颜色的数量在1∼2之间,那么显然这种颜色不能被消完,则可以剪枝。
然后是最优性剪枝,注意到虽然掉落这个现象很复杂,但他并不能在横向上移动,也就是说,横向上的移动,必须要通过交换来实现。
那么考虑一个颜色color。
如果某一列该颜色有1∼2个,那么它自己当然是无法自我消灭的,所以肯定要通过横向移动来得到其它列的“帮助”,比如离他隔的最近的且有该颜色的列。
那么我们可以取一个列,他只有1∼2个颜色color,且他离最近的可以”帮助”它的列最远,设这个距离-1为D color,那么我们的操作至少要把所有颜色的D值消到0。
1、校验和(checksum.cpp)【问题描述】在信息传输中,有许多种检验方式。
下面介绍一种比较简单的检验方式:假定传输的信息全部由大写字母和空格组成,并由大写字母开始和结束;大写字母编号为字母顺序:A=1,B=2,…,Z=26,空格的编号为0;校验和即为对应位置上的字符编号乘以位置之积的和。
注意空格也占用位置。
如ACM:1*1+2*3+3*13 = 46;MID CENTRAL: 1*13+2*9+3*4+4*0+5*3+6*5+7*14+8*20+9*18+ 10*1+11*12 = 650。
【输入格式】第一行为正整数t(≤1000),表示测试数据组数;接下来每行为一个信息字符串,仅由大写字母和空格组成,其长度不超过300。
【输出格式】对于每行信息,输出其校验和。
【输入输出样例】2、危险的民主(danger.cpp)【问题描述】在全民选举中,投票者被分成K个组,如果超过半数的组投赞成票,决议就可以通过。
每组是投赞成票还是反对票也由每组内部投票决定,若这一组有超过半数的人投赞成票,那么这一组就投赞成票。
例如有3组,分别有5,5,7人,那么,至少要有6个人赞成决议才能通过。
(即第一组和第二组各三人。
)注意到共有17人,只需要6人赞成就有可能通过,所以本题题目叫“危险的民主”已知组数和每组的人数,计算通过决议至少需要多少人赞成。
【输入格式】第一行是组数K(≤10001);第二行有K个数,分别是每一组的人数。
其中K以及每组的人数都是奇数,总人数不会超过108。
【输出格式】输出至少需要投赞成票的人数。
【输入输出样例】3、整除性问题(factorial.cpp)【问题描述】输入m和n,判断n是否能被m!整除。
【输入格式】第一行是正整数t(≤10),表示数据组数。
接下来t行,每行两个正整数m 和n(m,n≤2*109)。
【输出格式】对于每一组数据,输出“yes”或“no”表示n是否整除m!。
【输入输出样例】4、等差序列(sequence.cpp)【问题描述】输入一个非负整数的非递减序列,求其中成等差序列的子序列的个数。
NOIP历年复赛提高组试题(2004-2013)第十届全国信息学奥林匹克分区联赛(NOIP2004)复赛试题(提高组竞赛用时:3小时)1、津津的储蓄计划(Save.pas/dpr/c/cpp)【问题描述】津津的零花钱一直都是自己管理。
每个月的月初妈妈给津津300元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同。
为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在她那里,到了年末她会加上20%还给津津。
因此津津制定了一个储蓄计划:每个月的月初,在得到妈妈给的零花钱后,如果她预计到这个月的月末手中还会有多于100元或恰好100元,她就会把整百的钱存在妈妈那里,剩余的钱留在自己手中。
例如11月初津津手中还有83元,妈妈给了津津300元。
津津预计11月的花销是180元,那么她就会在妈妈那里存200元,自己留下183元。
到了11月月末,津津手中会剩下3元钱。
津津发现这个储蓄计划的主要风险是,存在妈妈那里的钱在年末之前不能取出。
有可能在某个月的月初,津津手中的钱加上这个月妈妈给的钱,不够这个月的原定预算。
如果出现这种情况,津津将不得不在这个月省吃俭用,压缩预算。
现在请你根据2004年1月到12月每个月津津的预算,判断会不会出现这种情况。
如果不会,计算到2004年年末,妈妈将津津平常存的钱加上20%还给津津之后,津津手中会有多少钱。
【输入文件】输入文件save.in包括12行数据,每行包含一个小于350的非负整数,分别表示1月到12月津津的预算。
【输出文件】输出文件save.out包括一行,这一行只包含一个整数。
如果储蓄计划实施过程中出现某个月钱不够用的情况,输出-X,X表示出现这种情况的第一个月;否则输出到2004年年末津津手中会有多少钱。
【样例输入1】290230908020060【样例输出2】15802、合并果子(fruit.pas/dpr/c/cpp)【问题描述】在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。
第十届全国信息学奥林匹克分区联赛(NOIP2004)复赛试题(提高组竞赛用时:3小时)1、津津的储蓄计划(Save.pas/dpr/c/cpp)【问题描述】津津的零花钱一直都是自己管理。
每个月的月初妈妈给津津300元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同。
为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在她那里,到了年末她会加上20%还给津津。
因此津津制定了一个储蓄计划:每个月的月初,在得到妈妈给的零花钱后,如果她预计到这个月的月末手中还会有多于100元或恰好100元,她就会把整百的钱存在妈妈那里,剩余的钱留在自己手中。
例如11月初津津手中还有83元,妈妈给了津津300元。
津津预计11月的花销是180元,那么她就会在妈妈那里存200元,自己留下183元。
到了11月月末,津津手中会剩下3元钱。
津津发现这个储蓄计划的主要风险是,存在妈妈那里的钱在年末之前不能取出。
有可能在某个月的月初,津津手中的钱加上这个月妈妈给的钱,不够这个月的原定预算。
如果出现这种情况,津津将不得不在这个月省吃俭用,压缩预算。
现在请你根据2004年1月到12月每个月津津的预算,判断会不会出现这种情况。
如果不会,计算到2004年年末,妈妈将津津平常存的钱加上20%还给津津之后,津津手中会有多少钱。
【输入文件】输入文件save.in包括12行数据,每行包含一个小于350的非负整数,分别表示1月到12月津津的预算。
【输出文件】输出文件save.out包括一行,这一行只包含一个整数。
如果储蓄计划实施过程中出现某个月钱不够用的情况,输出-X,X表示出现这种情况的第一个月;否则输出到2004年年末津津手中会有多少钱。
【样例输入1】29023028020030017034050908020060【样例输出1】-7【样例输入2】29023028020030017033050908020060【样例输出2】1580【问题描述】在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。
Day1铺地毯【问题描述】为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯。
一共有n 张地毯,编号从1 到n。
现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上。
地毯铺设完成后,组织者想知道覆盖地面某个点的最上面的那张地毯的编号。
注意:在矩形地毯边界和四个顶点上的点也算被地毯覆盖。
【输入】输入文件名为 carpet.in。
输入共 n+2 行。
第一行,一个整数 n,表示总共有n 张地毯。
接下来的 n 行中,第i+1 行表示编号i 的地毯的信息,包含四个正整数a,b,g,k,每两个整数之间用一个空格隔开,分别表示铺设地毯的左下角的坐标(a,b)以及地毯在x轴和y 轴方向的长度。
第 n+2 行包含两个正整数x 和y,表示所求的地面的点的坐标(x,y)。
【输出】输出文件名为 carpet.out。
输出共 1 行,一个整数,表示所求的地毯的编号;若此处没有被地毯覆盖则输出-1。
【输入输出样例 1】【输入输出样例说明】如下图,1 号地毯用实线表示,2 号地毯用虚线表示,3 号用双实线表示,覆盖点(2,2)的最上面一张地毯是3 号地毯。
【输入输出样例 2】【输入输出样例说明】如上图,1 号地毯用实线表示,2 号地毯用虚线表示,3 号用双实线表示,点(4,5)没有被地毯覆盖,所以输出-1。
【数据范围】对于 30%的数据,有n≤2;对于 50%的数据,0≤a, b, g, k≤100;对于 100%的数据,有0≤n≤10,000,0≤a, b, g, k≤100,000。
【一句话题意】给定n个按顺序覆盖的矩形,求某个点最上方的矩形编号。
【考察知识点】枚举【思路】好吧我承认看到图片的一瞬间想到过二维树状数组和二维线段树。
置答案ans=-1,按顺序枚举所有矩形,如果点在矩形内则更新ans。
注意题中给出的不是对角坐标,实际上是(a,b)与(a+g,b+k)。
还有一种办法可以从n到1枚举矩形,一旦在矩形内就直接输出,可能会快一点。
不过对于这题的范围什么都是浮云。
恩,写完这题一看还没过8:30【时间复杂度】O(n)选择客栈【问题描述】丽江河边有 n 家很有特色的客栈,客栈按照其位置顺序从1 到n 编号。
每家客栈都按照某一种色调进行装饰(总共k 种,用整数0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均有各自的最低消费。
两位游客一起去丽江旅游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中。
晚上,他们打算选择一家咖啡店喝咖啡,要求咖啡店位于两人住的两家客栈之间(包括他们住的客栈),且咖啡店的最低消费不超过p。
他们想知道总共有多少种选择住宿的方案,保证晚上可以找到一家最低消费不超过p元的咖啡店小聚。
【输入】输入文件 hotel.in,共n+1 行。
第一行三个整数 n,k,p,每两个整数之间用一个空格隔开,分别表示客栈的个数,色调的数目和能接受的最低消费的最高值;接下来的 n 行,第i+1 行两个整数,之间用一个空格隔开,分别表示i 号客栈的装饰色调和i 号客栈的咖啡店的最低消费。
【输出】输出文件名为 hotel.out。
输出只有一行,一个整数,表示可选的住宿方案的总数。
【输入输出样例 1】【输入输出样例说明】2 人要住同样色调的客栈,所有可选的住宿方案包括:住客栈①③,②④,②⑤,④⑤,但是若选择住4、5 号客栈的话,4、5 号客栈之间的咖啡店的最低消费是4,而两人能承受的最低消费是3 元,所以不满足要求。
因此只有前3 种方案可选。
【数据范围】对于 30%的数据,有n≤100;对于 50%的数据,有n≤1,000;对于 100%的数据,有2≤n≤200,000,0<k≤50,0≤p≤100, 0≤最低消费≤100。
【一句话题意】合法区间[l,r]定义:l,r的色调相同,且[l,r]之间存在一个最低消费不超过p。
求合法区间总数。
【考察知识点】二分查找/枚举【思路】贴吧神吐槽:CCF收了丽江多少钱?看完题目后不知所云,再多看几遍,一个O(n^3)的算法有了一点雏形。
用两层循环枚举区间的左右端点l、r,再用一层循环判断区间内是否有可行的咖啡店,累计即可。
这个算法思维难度和编程难度都非常低,但是只能过30%的数据,可以作为对拍程序备份。
再仔细思考,发现题中合法区间的限制条件其实很强。
首先区间端点的色调必须相同,其次区间内必须要存在一个咖啡店最低消费不超过P。
因此,如果我们用一层循环枚举左端点,并很快找到右端点的可行数,那么题目就能解决了。
这里置答案为变量ans,千万注意类型要为int64,昨天我就手抽打模板时直接打了ans:longint,超级大杯具!!!这里首先要用到区间部分和优化。
设sum [i,j]为前i个客栈中,色调为j的客栈总数,那么:sum[i,j]=sum[i-1,j] (color[i]<>j)sum[i,j]=sum[i-1,j]+1 (color[i]=j)这里要用O(NK)的复杂度,是算法的瓶颈所在,不过对于题中的数据范围已经足够了。
并且具体实现可以先用数组赋值sum[i]=sum[i-1],然后再为sum[i,color[i]]+1,应该会快很多。
我们还需要解决的问题就是,已知了L,如何快速找到R的可行范围?再次注意区间内必须要存在一个咖啡店最低消费不超过P。
因此,如果L就是一个最低消费不超过P的咖啡店,那么R可以取到[L+1,n]中所有色调为color[L]的客栈,即ans=ans+sum[n,color[L]]-sum[L,color[L]];如果L是一个最低消费超过P的咖啡店,那么我们要找到一个T∈[L+1,n],且咖啡店T的最低消费不超过P,那么R就可以取到[T,n]中所有色调为color[L]的客栈,即ans=ans+sum[n,color[L]]-sum[T-1,color[L]]。
问题是我们如何找到这个T,其实很简单,二分查找即可。
再次预设一个数组,保存所有最低消费不超过P的咖啡店序号,二分查找L即可。
注意这里L一定不存在这个数组中,因此找到的应该是最靠近L且大于L的序号,细节处理很重要。
找不到返回-1,不用累加ans就是了。
目测写完这题已经只剩1:30时间,且未对拍,第三题鸭梨巨大。
【时间复杂度】O(nk+nlogn)mayan 游戏【问题描述】Mayan puzzle 是最近流行起来的一个游戏。
游戏界面是一个7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上。
游戏通关是指在规定的步数内消除所有的方块,消除方块的规则如下:1、每步移动可以且仅可以沿横向(即向左或向右)拖动某一方块一格:当拖动这一方块时,如果拖动后到达的位置(以下称目标位置)也有方块,那么这两个方块将交换位置(参见输入输出样例说明中的图6 到图7);如果目标位置上没有方块,那么被拖动的方块将从原来的竖列中抽出,并从目标位置上掉落(直到不悬空,参见下面图1 和图2);2、任一时刻,如果在一横行或者竖列上有连续三个或者三个以上相同颜色的方块,则它们将立即被消除(参见图1 到图3)。
注意:a) 如果同时有多组方块满足消除条件,几组方块会同时被消除(例如下面图4,三个颜色为1 的方块和三个颜色为2 的方块会同时被消除,最后剩下一个颜色为2 的方块)。
b) 当出现行和列都满足消除条件且行列共享某个方块时,行和列上满足消除条件的所有方块会被同时消除(例如下面图5 所示的情形,5 个方块会同时被消除)。
3、方块消除之后,消除位置之上的方块将掉落,掉落后可能会引起新的方块消除。
注意:掉落的过程中将不会有方块的消除。
上面图 1 到图3 给出了在棋盘上移动一块方块之后棋盘的变化。
棋盘的左下角方块的坐标为(0, 0),将位于(3, 3)的方块向左移动之后,游戏界面从图1 变成图2 所示的状态,此时在一竖列上有连续三块颜色为4 的方块,满足消除条件,消除连续3 块颜色为4 的方块后,上方的颜色为3 的方块掉落,形成图3 所示的局面。
【输入】输入文件 mayan.in,共6 行。
第一行为一个正整数 n,表示要求游戏通关的步数。
接下来的 5 行,描述7*5 的游戏界面。
每行若干个整数,每两个整数之间用一个空格隔开,每行以一个0 结束,自下向上表示每竖列方块的颜色编号(颜色不多于10 种,从1 开始顺序编号,相同数字表示相同颜色)。
输入数据保证初始棋盘中没有可以消除的方块。
【输出】输出文件名为 mayan.out。
如果有解决方案,输出n 行,每行包含3 个整数x,y,g,表示一次移动,每两个整数之间用一个空格隔开,其中(x,y)表示要移动的方块的坐标,g 表示移动的方向,1 表示向右移动,-1 表示向左移动。
注意:多组解时,按照x 为第一关健字,y 为第二关健字,1优先于-1,给出一组字典序最小的解。
游戏界面左下角的坐标为(0,0)。
如果没有解决方案,输出一行,包含一个整数-1。
【输入输出样例 1】【输入输出样例说明】按箭头方向的顺序分别为图 6 到图11样例输入的游戏局面如上面第一个图片所示,依次移动的三步是:(2,1)处的方格向右移动,(3,1)处的方格向右移动,(3,0)处的方格向右移动,最后可以将棋盘上所有方块消除。
【数据范围】对于 30%的数据,初始棋盘上的方块都在棋盘的最下面一行;对于 100%的数据,0 < n≤5。
【一句话题意】给定一个存在重力的矩阵,每次只能向左或右交换方块,连续3个或以上的方块群会被消除。
求操作次数为N时的操作步骤。
【考察知识点】DFS【思路】我实在是忍不住吐槽了,第三题竟然是iPhone上Mayan Puzzle游戏的完全复制。
见贴吧此帖子。
威锋上果然有完全题解啊,第14关果然是样例啊有木有!!!人类智力威武,Orz…………..对于这种完全裸搜索,固定搜索顺序,掐死搜索深度,基本无任何剪枝的题目彻底无语。
恩,吐槽完毕。
注意注意,第一页描述这题每个测试点时间限制是3S,我当时就震惊了!首先马上确定这是搜索题目,抛弃所有动规贪心等等。
然后锁定DFS,因为题中已经限定搜索深度,BFS是自找MLE。
再确定状态存储方式,我是将输入逆时针转90°后用数组保存,因此坐标之类的要特别注意。
然后,然后就没什么特别的了,搜素顺序题目已经给了。
设过程down(i),表示将第i列的所有方块下沉。
设函数clear,分行列清空后返回是否可以清空,这里用到连续区间指针l、r优化,类似前向星分组时的操作。
于是:while clear dofor i:=1 to 5 dodown(i);注意在此之前如果有方块一交换就往下掉,那么就down交换的那两列。