NOIP 2010
tags:
机器翻译
Solution
维护一个队列, 每次从词典中查词时将单词加入队列(代表内存), 当内存满的时候, 从队首弹出一个代表清空最早的单词.
Code
#include<iostream>
#include<cstdio>
#include<queue>
#define N 1005
using namespace std;
queue<int>que;
int vis[N];
int main(){
int n,m,q,ans=0;
scanf("%d%d",&m,&n);
for(int i=1;i<=n;++i){
scanf("%d",&q);
if(!vis[q]){
if(que.size()==m){
vis[que.front()]=false;
que.pop();
}
que.push(q);
vis[q]=1;
ans++;
}
}
printf("%d",ans);
return 0;
}
乌龟棋
Solution
比较原始的动态规划, \(f(i,j,k,l)\)表示使用了\(i,j,k,l\)张\(1,2,3,4\)的牌, 然后依次枚举\(l,k,j,i\)来更新\(f(i,j,k,l)\).
Code
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#define N 45
using namespace std;
int dp[N][N][N][N];
int s1,s2,s3,s4;
int value[505];
int n,m,s;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%d",&value[i]);
for(int i=1;i<=m;++i){
scanf("%d",&s);
if(s==1)s1++;if(s==2)s2++;
if(s==3)s3++;if(s==4)s4++;
}
int ans=0;
for(int d=0;d<=s4;++d)
for(int c=0;c<=s3;++c)
for(int b=0;b<=s2;++b)
for(int a=0;a<=s1;++a){
int siz=a+b*2+c*3+d*4;
if(siz>n)continue;
dp[a][b][c][d]+=value[siz+1];
int ma=dp[a][b][c][d];
if(a)ma=max(ma,dp[a-1][b][c][d]+value[siz+1]);
if(b)ma=max(ma,dp[a][b-1][c][d]+value[siz+1]);
if(c)ma=max(ma,dp[a][b][c-1][d]+value[siz+1]);
if(d)ma=max(ma,dp[a][b][c][d-1]+value[siz+1]);
dp[a][b][c][d]=ma;
// cout<<dp[a][b][c][d]<<endl;
if(siz+1==n)ans=max(ma,ans);
}
printf("%d",ans);
// system("pause");
return 0;
}
关押罪犯
做法
并查集, 最开始有\(2n\)个集合, 代表每个点所属的集合和敌对的人所属的集合, 然后将所有敌对关系从大到小排序, 依次将一个点加入另一个点的敌对集合, 直到无法再加时就是最终的答案.
Code
#include<iostream>
#include<cstring>
#include<cstdio>
#define N 515
#define inf 0x3f3f3f3f
using namespace std;
int dx[N]={0,0,-1,1};
int dy[N]={1,-1,0,0};
int h[N][N];
int be[N][N];
int also[N];
bool vis[N][N];
int n,m;
int color;
int flag=inf,en;
int visit[N];
struct Segment{
int u,v;
inline bool operator<(const Segment& s)const{
if(v!=s.v)return v>s.v;return u<s.u;
}
}e[N];
int tot;
inline bool Chu(int x,int y){
if(x<1||y<1||x>n||y>m)return false;
return true;
}
void dfs(int x,int y,int f){
vis[x][y]=true;
for(int i=0;i<4;++i){
int xx=dx[i]+x,yy=dy[i]+y;
if(vis[xx][yy])continue;
if(!Chu(xx,yy))continue;
if(h[xx][yy]>=h[x][y])continue;
be[xx][yy]=f;
if(xx==n)flag=min(flag,yy),en=max(en,yy);
dfs(xx,yy,f);
}
}
int main(){
scanf("%d%d",&n,&m);
if(n==1){
cout<<"1\n4";
return 0;
}
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
scanf("%d",&h[i][j]);
// cout<<"*****************\n";
for(int i=1;i<=m;++i){
memset(vis,false,sizeof(vis));
if(h[1][i-1]>h[1][i])continue;
if(h[1][i+1]>h[1][i])continue;
flag=inf;
dfs(1,i,i);if(flag==inf)continue;
e[++tot]=(Segment){flag,en};
// cout<<flag<<' '<<en<<' '<<i<<endl;
}
int ans=0;
for(int i=1;i<=m;++i){
if(!be[n][i])++ans;
// cout<<be[n][i]<<' ';
}
if(ans){
printf("0\n%d",ans);
return 0;
}
int l,r=1;int maxl,pos;ans=0;
while(r<m+1){
for(int i=1;i<=tot;++i){
if(e[i].v>500||e[i].u>500)break;
if(e[i].u<=r&&!visit[i])
if(e[i].v>maxl){
pos=i,maxl=e[i].v;
}
}
visit[pos]=true;
r=maxl+1;ans++;
} if(!ans)ans=1;
printf("1\n%d",ans);
// system("pause");
return 0;
}
引水入城
Solution
并没有像他们说的那样会超时, 虽然使用了非常暴力的做法来处理.首先找出每个点能覆盖的处在沙漠中点的区间.然后做线段覆盖, 我处理的真的是非常随便.注意有一个数据是沙漠也是城市, 特判过; 另外如果一个临湖点比另一个一个相邻的点低, 就不需要遍历这个点了, 因为是肯定是它的子集.
Code
#include<iostream>
#include<cstring>
#include<cstdio>
#define N 515
#define inf 0x3f3f3f3f
using namespace std;
int dx[N]={0,0,-1,1};
int dy[N]={1,-1,0,0};
int h[N][N];
int be[N][N];
int also[N];
bool vis[N][N];
int n,m;
int color;
int flag=inf,en;
int visit[N];
struct Segment{
int u,v;
inline bool operator<(const Segment& s)const{
if(v!=s.v)return v>s.v;return u<s.u;
}
}e[N];
int tot;
inline bool Chu(int x,int y){
if(x<1||y<1||x>n||y>m)return false;
return true;
}
void dfs(int x,int y,int f){
vis[x][y]=true;
for(int i=0;i<4;++i){
int xx=dx[i]+x,yy=dy[i]+y;
if(vis[xx][yy])continue;
if(!Chu(xx,yy))continue;
if(h[xx][yy]>=h[x][y])continue;
be[xx][yy]=f;
if(xx==n)flag=min(flag,yy),en=max(en,yy);
dfs(xx,yy,f);
}
}
int main(){
scanf("%d%d",&n,&m);
if(n==1){
cout<<"1\n4";
return 0;
}
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
scanf("%d",&h[i][j]);
// cout<<"*****************\n";
for(int i=1;i<=m;++i){
memset(vis,false,sizeof(vis));
if(h[1][i-1]>h[1][i])continue;
if(h[1][i+1]>h[1][i])continue;
flag=inf;
dfs(1,i,i);if(flag==inf)continue;
e[++tot]=(Segment){flag,en};
// cout<<flag<<' '<<en<<' '<<i<<endl;
}
int ans=0;
for(int i=1;i<=m;++i){
if(!be[n][i])++ans;
// cout<<be[n][i]<<' ';
}
if(ans){
printf("0\n%d",ans);
return 0;
}
int l,r=1;int maxl,pos;ans=0;
while(r<m+1){
for(int i=1;i<=tot;++i){
if(e[i].v>500||e[i].u>500)break;
if(e[i].u<=r&&!visit[i])
if(e[i].v>maxl){
pos=i,maxl=e[i].v;
}
}
visit[pos]=true;
r=maxl+1;ans++;
} if(!ans)ans=1;
printf("1\n%d",ans);
// system("pause");
return 0;
}
NOIP 2010的更多相关文章
- 洛谷 P1525 关押罪犯==codevs 1069 关押罪犯[NOIP 2010]
P1525 关押罪犯 513通过 1.4K提交 题目提供者该用户不存在 标签图论并查集NOIp提高组2010 难度普及+/提高 提交该题 讨论 题解 记录 最新讨论 咳咳.竟MLE了. 囧.运行时错误 ...
- NOIp 2010/Luogu P1525 关押罪犯 【二分图/并查集】 By cellur925
题目传送门 感想:相信自己的想法!继续挖掘! 读完题目后:看到的最大值最小?二分答案啊!再仔细一看:wi达到了1e9,二分可能费点劲.(其实真的是可以的)而且check函数貌似并没有什么行之有效的写法 ...
- NOIP 2010题解
唔..NOIP2010比较简单,总体感觉不错. Problem 1: 机器翻译 水题,队列的简单应用. 读入时判断是否在内存中,可以用hash优化.如果不在内存中push进内存,放不下了pop hea ...
- noip 2010 关押罪犯 (二分图染色 并茶几)
/* 二分图染色版本 两个监狱对应二部图的两部分 在给定的怨气值里二分 对于每一个Ci 进行染色判断是否合法 染色的时候 如果这条边的ci > Ci 这两个人就带分开 即染成不同的颜色 如果染色 ...
- [NOIP 2010]饮水入城 搜索+贪心
考试的时候写了个dfs找出来了,最后处理的时候想到了贪心,但是正确性没有想通.然后想了想动规,也没想通.最后没办法,用状态的话用了个状压,弄了40分. 正解是bfs+贪心.Dfs也有过的. 下面题解引 ...
- [NOIP 2010] 引水入城
搜索+贪心. 参考博客:http://blog.sina.com.cn/s/blog_8442ec3b0100xib1.html 主要是要看出来,如果有解的话,每个沿湖城市能够流到的范围是连续的区间. ...
- noip 2010 三国游戏
三国游戏 三国游戏 描述 小涵很喜欢电脑游戏,这些天他正在玩一个叫做<三国>的游戏. 在游戏中,小涵和计算机各执一方,组建各自的军队进行对战.游戏中共有N 位武将(N为偶数且不小于4),任 ...
- noip 2010 关押罪犯 二分答案+二分图染色 || 并查集
题目链接 题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值&q ...
- noip 2010 数字统计
数位dp解水题 luogu1179 dp[i][j]表示 有i位,且首位是j(包括0) 的 ‘2’的个数 dp[i][j]={ Σ(dp[i-1][k]),j!=2; Σ(dp[i-1][k])+va ...
随机推荐
- POJ3468:A Simple Problem with Integers——题解
http://poj.org/problem?id=3468 实现一个线段树,能够做到区间修改和区间查询和. 明显板子题. #include<cstdio> #include<cma ...
- SPOJ694/DISUBSTR:Distinct Substrings——题解
https://vjudge.net/problem/SPOJ-DISUBSTR https://www.luogu.org/problemnew/show/SP694 http://www.spoj ...
- BZOJ1037 [ZJOI2008]生日聚会Party 【DP】
1037: [ZJOI2008]生日聚会Party Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2800 Solved: 1654 [Submi ...
- [zhuan]Android程序的真正入口Application
http://blog.csdn.net/coding_or_coded/article/details/6602560 接触android已经有一段时间了,一直以为android程序的入口是配置文件 ...
- mysql主从同步加读写分离
首先主从同步,一旦建立,指定了用户,就不能更改了,否则会有错误.1063 Error 'Duplicate entry '%-test-' for key 'PRIMARY'' on query. D ...
- angularJS修改 品优购修改品牌(新增和修改用同一个方法)
前端代码 brand.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"&g ...
- redis中如何对 key 进行分类
因为redis中的 hash是不支持设置过期时间的,如果我们要 设置过期时间,还要分类存储,可以用下面折中的方法 其实就是我们把 key 定义的有规律一些,通过在key的字符串内部 分类,上图只是因为 ...
- 《python核心编程》读书笔记--第18章 多线程编程
18.1引言 在多线程(multithreaded,MT)出现之前,电脑程序的运行由一个执行序列组成.多线程对某些任务来说是最理想的.这些任务有以下特点:它们本质上就是异步的,需要多个并发事务,各个事 ...
- Codeforces Round #398 (Div. 2) A B C D 模拟 细节 dfs 贪心
A. Snacktower time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- Gaby And Addition Gym - 101466A (初学字典树)
Gaby is a little baby who loves playing with numbers. Recently she has learned how to add 2 numbers ...