唔..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题解的更多相关文章

  1. 洛谷NOIp热身赛题解

    洛谷NOIp热身赛题解 A 最大差值 简单树状数组,维护区间和.区间平方和,方差按照给的公式算就行了 #include<bits/stdc++.h> #define il inline # ...

  2. 洛谷 P1525 关押罪犯==codevs 1069 关押罪犯[NOIP 2010]

    P1525 关押罪犯 513通过 1.4K提交 题目提供者该用户不存在 标签图论并查集NOIp提高组2010 难度普及+/提高 提交该题 讨论 题解 记录 最新讨论 咳咳.竟MLE了. 囧.运行时错误 ...

  3. NOIp 2010/Luogu P1525 关押罪犯 【二分图/并查集】 By cellur925

    题目传送门 感想:相信自己的想法!继续挖掘! 读完题目后:看到的最大值最小?二分答案啊!再仔细一看:wi达到了1e9,二分可能费点劲.(其实真的是可以的)而且check函数貌似并没有什么行之有效的写法 ...

  4. [NOIP 2010]饮水入城 搜索+贪心

    考试的时候写了个dfs找出来了,最后处理的时候想到了贪心,但是正确性没有想通.然后想了想动规,也没想通.最后没办法,用状态的话用了个状压,弄了40分. 正解是bfs+贪心.Dfs也有过的. 下面题解引 ...

  5. 历年NOIP选题题解汇总

    联赛前上vijos板刷往年联赛题,使用在线编辑编写代码,祝我rp++. 废话不多说,挑比较有意思的记一下. 题目是按照年份排序的,最早只到了03年. 有些题目因为 我还没写/很早之前写的忘了 所以就没 ...

  6. NOIP 2010

    tags: NOIP 并查集 动态规划 搜索 categories: 信息学竞赛 总结 机器翻译 乌龟棋 关押罪犯 引水入城 机器翻译 Solution 维护一个队列, 每次从词典中查词时将单词加入队 ...

  7. noip 2010 关押罪犯 (二分图染色 并茶几)

    /* 二分图染色版本 两个监狱对应二部图的两部分 在给定的怨气值里二分 对于每一个Ci 进行染色判断是否合法 染色的时候 如果这条边的ci > Ci 这两个人就带分开 即染成不同的颜色 如果染色 ...

  8. Luogu P1082 同余方程(NOIP 2012) 题解报告

    题目传送门 [题目大意] 求关于x的同余方程 ax≡1(mod b)的最小整数解. [思路分析] 由同余方程的有关知识可得,ax≡1(mod b)可以化为ax+by=1,此方程有解当且仅当gcd(a, ...

  9. [NOIP 2010] 引水入城

    搜索+贪心. 参考博客:http://blog.sina.com.cn/s/blog_8442ec3b0100xib1.html 主要是要看出来,如果有解的话,每个沿湖城市能够流到的范围是连续的区间. ...

随机推荐

  1. ios 消息转发初探

    有时候服务器的接口文档上一个数据写的是string类型,这时候你就会直接把它赋值给一个label. 问题来了,有时候这个string的确是string,没有问题,有时候又是NSNumber,当然不管三 ...

  2. mac pro在公司连WiFi正常,回家回宿舍就找不到WiFI信号,需要重启才能找到WiFI热点

    解决办法:修改路由器的频段到1-11这个范围. 之前一直没时间去找原因,项目也急,这几天项目不是特别急了,就找找了,原因. 因为之前还是好好的,主要是之前有次修改了下路由器的配置. 改了下默认的发送频 ...

  3. C语言生成服从均匀分布, 瑞利分布, 莱斯分布, 高斯分布的随机数

    用c语言 产生服从均匀分布, 瑞利分布,莱斯分布,高斯分布的随机数   一,各个分布对应的基本含义: 1. 均匀分布或称规则分布,顾名思义,均匀的,不偏差的.植物种群的个体是等距分布,或个体之间保持一 ...

  4. linq group join

    本篇介绍Linq的Group和Join操作,继续使用<Linq 学习(3) 语法结构>中介绍的数据源. GroupGroup是进行分组操作,同SQL中的Group By类似.原型如下: p ...

  5. centos 7.0 安装

    最小化安装的  主要查看硬盘使用时间 需要安装 smartmontools 这个 [root@localhost ~]# yum install -y smartmontools 已加载插件:fast ...

  6. GoLang之协程

    GoLang之协程 目前,WebServer几种主流的并发模型: 多线程,每个线程一次处理一个请求,在当前请求处理完成之前不会接收其它请求:但在高并发环境下,多线程的开销比较大: 基于回调的异步IO, ...

  7. svn 回滚到某个版本

    用svn merge命令来进行回滚. 回滚的操作过程如下: 1.保证我们拿到的是最新代码: svn update 假设最新版本号是28. 2.然后找出要回滚的确切版本号: svn log 假设根据sv ...

  8. Hibernate 查询MatchMode的四种模式

    Hibernate 查询MatchMode的四种模式 MatchMode.START:字符串在最前面的位置.相当于"like 'key%'" MatchMode.END:字符串在最 ...

  9. java中跳出if判断

    今天学到的一点儿新东西一个if判断里面有好多东西,紧接着还有其他代码,不能使用return来结束这个if判断这时候,就需要这样: out:if (!"null".equals(re ...

  10. linux 驱动程序中断号的申请

    1.linux下查看硬中断与软中断 硬中断:/proc/interrupts 软中断:/proc/softirqs 往往一些硬件中断号都是跟CPU所分配的硬件中断号相匹配的. 即同类型的cpu可能对同 ...