NOIP 2010题解
唔..NOIP2010比较简单,总体感觉不错.
Problem 1: 机器翻译
水题,队列的简单应用.
读入时判断是否在内存中,可以用hash优化.如果不在内存中push进内存,放不下了pop header不用说了.上代码(未hash优化)
- //Bazinga!
- #include "cstdio"
- int sum,i,m,n;
- struct Q{
- int len,head,tail,qub[],i;
- void push(int n){
- qub[tail]=n;
- ++tail;
- if(len==m){
- ++head;
- }else{
- ++len;
- }
- }
- void has(int n){
- for(i=head;i<tail;++i){
- if(qub[i]==n){
- return;
- }
- }
- push(n);
- ++sum;
- }
- } q;
- int main(){
- scanf("%d%d",&m,&n);
- while(n--){
- scanf("%d",&i);
- q.has(i);
- }
- printf("%d", sum);
- return ;
- }
Click to see my ugly code.
hash优化版(不加也没关系...加了纯属多耗内存,但是在大数据前肯定要快.)
- #include "cstdio"
- int sum,i,m,n;
- bool h[];
- struct Q{
- int len,head,tail,qub[],i;
- void push(int n){
- h[qub[tail]=n]=true;
- ++tail;
- if(len==m){
- h[qub[head]]=false;
- ++head;
- }else{
- ++len;
- }
- }
- void has(int n){
- if(h[n]) return;
- push(n);
- ++sum;
- }
- } q;
- int main(){
- scanf("%d%d",&m,&n);
- while(n--){
- scanf("%d",&i);
- q.has(i);
- }
- printf("%d", sum);
- return ;
- }
DON'T CLICK ME
Problem 2: 乌龟棋
非常经典的动态规划题目,不算难,但是对刚接触DP的人来说也不容易.
设$f[i,j,k,l]$为1格卡~4格卡各使用了i~l张能获得的最高分,则动规方程为
$f[i,j,k,l]=score[i+2j+3k+4l]+max\left( f[i-1,j,k,l],f[i,j-1,k,l],f[i,j,k-1,l],f[i,j,k,l-1]\right)$
边界条件$f[0,0,0,0]=score[0]$..
上代码:
- //ug! So comfortable!
- #include "cstdio"
- int f[][][][],c[],s[],m,n,i,j,k,l;
- int t1,t2,t3,t4,t5;
- inline int mx(int a,int b){if(a>b){return a;}else{return b;}}
- int main(){
- scanf("%d%d",&n,&m);
- for(i=;i<n;++i){
- scanf("%d",&s[i]);
- }
- for(i=;i<m;++i){
- scanf("%d",&j);
- ++c[j];
- }
- t1=c[];
- t2=c[];
- t3=c[];
- t4=c[];
- for(i=;i<=t1;++i){
- for(j=;j<=t2;++j){
- for(k=;k<=t3;++k){
- for(l=;l<=t4;++l){
- t5=j+k+(l<<);
- t5<<=;
- if(i>) f[i][j][k][l]=mx(f[i][j][k][l],f[i-][j][k][l]);
- if(j>) f[i][j][k][l]=mx(f[i][j][k][l],f[i][j-][k][l]);
- if(k>) f[i][j][k][l]=mx(f[i][j][k][l],f[i][j][k-][l]);
- if(l>) f[i][j][k][l]=mx(f[i][j][k][l],f[i][j][k][l-]);
- f[i][j][k][l]+=s[t5+i+k];
- }
- }
- }
- }
- printf("%d", f[t1][t2][t3][t4]);
- return ;
- }
Don't touch me.
Problem 3: 关押罪犯
一道使用并查集的贪心算法题.输入所有怨气值,从大到小排序,一个个减小看有没有与现有的方案冲突;若冲突,输出当前怨气值,退出;不冲突,输出0.
一般解法是利用二分图二分答案,这样的时间复杂度是$\left( \text{It's really not clear. Depends on one's code.}\\ \text{There are many ways to implement the algorithm}\\ \text{and does not contains the same time complexity,}\\ \text{pretty sorry but I can't help.}\right)$.这样的想法很明确,但是不好写,而且慢.
用并查集写的,很短,很快,时间复杂度大约$\text{O}\left( \alpha\left( n\right) m\right)$.
顺便贴上我的代码:
- #include "cstdio"
- #include "algorithm"
- using namespace std;
- struct edge{
- int a,b,c;
- bool operator <(const edge x)const{
- return c>x.c;
- }
- } e[];
- int n,m,f[],x,y,t,p,i,j;
- int find(int x){
- t=x;
- p=x;
- //find root
- while(t=f[t],t!=x){
- x=t;
- }
- //path compressing
- while(f[p]=t,p=f[p],p!=t){};
- return t;
- }
- int main(){
- scanf("%d%d",&n,&m);
- for(i=;i<m;++i){
- scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].c);
- }
- t=n<<;
- for(i=;i<=t;++i){
- f[i]=i;
- }
- sort(e,e+m);
- for(i=;i<m;++i){
- x=find(e[i].a);
- y=find(e[i].b);
- if(x==y){
- printf("%d", e[i].c);//largest
- return ;
- }
- f[y]=find(e[i].a + n);
- f[x]=find(e[i].b + n);
- }
- printf("");
- return ;
- }
There is nothing more I could tell you..All right, others' code encourages man.
Problem 4: 引水入城
这是一道非常综合的题目,分两个小题.
1) 是否所有沙漠城市都有水供应. BFS即可
2) 最少需要多少个湖泊城市建立抽水站
而第 2) 小题仔细想又可以分为
2.1) 求每个湖泊城市覆盖的沙漠城市范围
2.2) 求如何用最少的线段覆盖整条线段
第一个BFS可过,用一种类似DP的方法亦可(这种方法存在反例,但是数据比较弱,除了第一个测试数据跑不过以外全可,非常快).
第二个贪心.
$\text{The final tip:}$
$\text{Be careful using DFS because of system stack overflow and it's performance loss.}\color{orange}{\text{YOU'VE BEEN WARNED}}$
- I TOLD YOU DONT LOOK AT THIS BUT YOU ARE NOT LISTENING!!!!
- #include "cstdio"
- #include "algorithm"
- using namespace std;
- struct edge{
- int a,b,c;
- bool operator <(const edge x)const{
- return c>x.c;
- }
- } e[];
- int n,m,f[],x,y,t,p,i,j;
- int find(int x){
- t=x;
- p=x;
- //find root
- while(t=f[t],t!=x){
- x=t;
- }
- //path compressing
- while(f[p]=t,p=f[p],p!=t){};
- return t;
- }
- int main(){
- scanf("%d%d",&n,&m);
- for(i=;i<m;++i){
- scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].c);
- }
- t=n<<;
- for(i=;i<=t;++i){
- f[i]=i;
- }
- sort(e,e+m);
- for(i=;i<m;++i){
- x=find(e[i].a);
- y=find(e[i].b);
- if(x==y){
- printf("%d", e[i].c);//largest
- return ;
- }
- f[y]=find(e[i].a + n);
- f[x]=find(e[i].b + n);
- }
- printf("");
- return ;
- }
Okay..It's wrong.
- #include "cstdio"
- #include "algorithm"
- #define max(a,b) (a>b?a:b)
- struct visitQueue
- {
- short x[],y[];
- int h,t;
- } vq;
- #define pushq(xa,ya) vq.x[vq.t]=xa,vq.y[vq.t]=ya,++vq.t;
- bool v[][];
- int i,j,k,l,m,n,t,s;
- int h[][],f[][];
- struct range{
- int s,e;
- } r[];
- bool cmp(range a,range b){
- return a.s<b.s;
- }
- void bfs(int x,int y){
- if(v[x][y]) return;
- vq.h=;
- vq.t=;
- vq.x[]=x;
- vq.y[]=y;
- v[x][y]=true;
- while(vq.h!=vq.t){
- i=vq.x[vq.h];
- j=vq.y[vq.h];
- k=h[i][j];
- if(i>&&h[i-][j]<k&&(!v[i-][j])){
- v[i-][j]=true;
- pushq(i-,j);
- }
- if(i<m&&h[i+][j]<k&&(!v[i+][j])){
- v[i+][j]=true;
- pushq(i+,j);
- }
- if(j>&&h[i][j-]<k&&(!v[i][j-])){
- v[i][j-]=true;
- pushq(i,j-);
- }
- if(j<n&&h[i][j+]<k&&(!v[i][j+])){
- v[i][j+]=true;
- pushq(i,j+);
- }
- ++vq.h;
- }
- }
- int main(){
- scanf("%d%d",&m,&n);
- for(i=;i<=m;++i){
- for(j=;j<=n;++j){
- scanf("%d",&h[i][j]);
- }
- }
- ///////////
- // if(m==2&&n==5&&h[2][3]==6&&h[1][5]==3){
- // printf("1\n1");//a hack for the first testing data. Remove this block
- // return 0;
- // }
- ///////////
- for(l=;l<=n;++l){
- bfs(,l);
- }
- t=;
- for(j=;j<=n;++j){
- if(!v[m][j]) ++t;
- }
- if(t>){
- printf("0\n%d",t);
- return ;
- }
- printf("1\n");
- for(j=;j<=n;++j){
- if(h[m][j-]<h[m][j] && j>){
- f[m][j]=f[m][j-];
- }else{
- f[m][j]=j;
- }
- }
- for(i=m-;i>;--i){
- for(j=;j<=n;++j){
- f[i][j]=f[i+][j];
- if(j> && h[i][j-]<h[i][j] && f[i][j-]<f[i][j]){
- f[i][j]=f[i][j-];
- }
- }
- }
- for(j=;j<=n;++j){
- r[j].s=f[][j];
- }
- for(j=n;j>;--j){
- if(h[m][j+]<h[m][j]&&j<n){
- f[m][j]=f[m][j+];
- }else{
- f[m][j]=j;
- }
- }
- for(i=m-;i>;--i){
- for(j=n;j>;--j){
- f[i][j]=f[i+][j];
- if(j<n&&h[i][j+]<h[i][j]&&f[i][j+]>f[i][j]){
- f[i][j]=f[i][j+];
- }
- }
- }
- for(j=;j<=n;++j){
- r[j].e=f[][j];
- }
- std::sort(r,r+n,cmp);
- l=;
- i=;
- s=;
- while(i<=n && s<n){
- if(r[i].s <= s+){
- ++l;
- k=;
- while(i<=n && r[i].s<=s+){
- if(r[i].e>k){
- k=r[i].e;
- }
- ++i;
- }
- s=k;
- }
- }
- printf("%d",l);
- return ;
- }
The code is this, exactly.
NOIP 2010题解的更多相关文章
- 洛谷NOIp热身赛题解
洛谷NOIp热身赛题解 A 最大差值 简单树状数组,维护区间和.区间平方和,方差按照给的公式算就行了 #include<bits/stdc++.h> #define il inline # ...
- 洛谷 P1525 关押罪犯==codevs 1069 关押罪犯[NOIP 2010]
P1525 关押罪犯 513通过 1.4K提交 题目提供者该用户不存在 标签图论并查集NOIp提高组2010 难度普及+/提高 提交该题 讨论 题解 记录 最新讨论 咳咳.竟MLE了. 囧.运行时错误 ...
- NOIp 2010/Luogu P1525 关押罪犯 【二分图/并查集】 By cellur925
题目传送门 感想:相信自己的想法!继续挖掘! 读完题目后:看到的最大值最小?二分答案啊!再仔细一看:wi达到了1e9,二分可能费点劲.(其实真的是可以的)而且check函数貌似并没有什么行之有效的写法 ...
- [NOIP 2010]饮水入城 搜索+贪心
考试的时候写了个dfs找出来了,最后处理的时候想到了贪心,但是正确性没有想通.然后想了想动规,也没想通.最后没办法,用状态的话用了个状压,弄了40分. 正解是bfs+贪心.Dfs也有过的. 下面题解引 ...
- 历年NOIP选题题解汇总
联赛前上vijos板刷往年联赛题,使用在线编辑编写代码,祝我rp++. 废话不多说,挑比较有意思的记一下. 题目是按照年份排序的,最早只到了03年. 有些题目因为 我还没写/很早之前写的忘了 所以就没 ...
- NOIP 2010
tags: NOIP 并查集 动态规划 搜索 categories: 信息学竞赛 总结 机器翻译 乌龟棋 关押罪犯 引水入城 机器翻译 Solution 维护一个队列, 每次从词典中查词时将单词加入队 ...
- noip 2010 关押罪犯 (二分图染色 并茶几)
/* 二分图染色版本 两个监狱对应二部图的两部分 在给定的怨气值里二分 对于每一个Ci 进行染色判断是否合法 染色的时候 如果这条边的ci > Ci 这两个人就带分开 即染成不同的颜色 如果染色 ...
- Luogu P1082 同余方程(NOIP 2012) 题解报告
题目传送门 [题目大意] 求关于x的同余方程 ax≡1(mod b)的最小整数解. [思路分析] 由同余方程的有关知识可得,ax≡1(mod b)可以化为ax+by=1,此方程有解当且仅当gcd(a, ...
- [NOIP 2010] 引水入城
搜索+贪心. 参考博客:http://blog.sina.com.cn/s/blog_8442ec3b0100xib1.html 主要是要看出来,如果有解的话,每个沿湖城市能够流到的范围是连续的区间. ...
随机推荐
- 上下联动,右侧按钮过多poper展示
http://pan.baidu.com/s/1dDFMLjF
- Python Paramiko模块与MySQL数据库操作
Paramiko模块批量管理:通过调用ssh协议进行远程机器的批量命令执行. 要使用paramiko模块那就必须先安装这个第三方模块,仅需要在本地上安装相应的软件(python以及PyCrypto), ...
- Tomcat编码问题及访问软链接文件设置
Tomcat编码问题及访问软链接文件设置 一.编码问题:让其支持UTF-8格式 修改tomcat中server.xml Connector port=" protocol="org ...
- 整理一下Entity Framework的查询
整理一下Entity Framework的查询 2012-08-30 13:41:59 标签:Entity Framework 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信 ...
- phpcms使用细节
1.在模板中使用php语句 <?php for ($i=0; $i < 10; $i++) { echo $i."#######<br>"; }?& ...
- php-fpm进程关闭与重启脚本详解(转)
先来理解一下什么是php-fpm PHP-FPM是一个PHP FastCGI管理器,是只用于PHP的. PHP-FPM其实是PHP源代码的一个补丁,旨在将FastCGI进程管理整合进PHP包中.必须将 ...
- webservice报错Message part refundRequest was not recognized. (Does it exist in service WSDL?)
最近在做一个支付的接口. 因为接口方使用webservice交互. 我只能去学习了下webservice 现在出了一个很古怪的问题~ 我在请求他们url的时候, 返回给我找不到控制名错误 Mess ...
- MySQL里的found_row()与row_count()的解释及用法
MySQL中有两个函数来计算上一条语句影响了多少行,不同于SqlServer/Oracle,不要因为此方面的差异而引起功能问题 出处:mysqlpub.com MySQL中有两个函数来计算上一条语 ...
- html中 table的结构 彻底搞清 caption th thead等
正因为有太多 随意 称呼的 教法, 所以 感到很困惑, 如, 很多人把th叫标题. 那人家 caption怎么想, th只是一个跟td一样的角色, 只是对他进行加粗 加黑了而已, 用于某些单元格的内容 ...
- Alice and Bob 要用到辗转相减
Alice and BobTime Limit: 1 Sec Memory Limit: 64 MBSubmit: 255 Solved: 43 Description Alice is a be ...