COCI 2016/2017 Round #5

Tuna

题目翻译

分析

水题,按题意模拟即可。

参考代码

#include<cstdio>
#include<algorithm>
using namespace std;int main() {freopen("tuna.in","r",stdin);freopen("tuna.out","w",stdout);int N,X;scanf("%d %d",&N,&X);int ans=0;for(int i=1;i<=N;i++) {int p1,p2,p3;scanf("%d %d",&p1,&p2);if(p1<p2)swap(p1,p2);if(p1-p2>X) {scanf("%d",&p3);ans+=p3;} else ans+=p1;}printf("%d\n",ans);return 0;
}

Pareto

题目翻译

这题题面真涨知识。。。

分析

稍加分析可发现,我们将账户余额从大到小排序后一个一个暴力比较即可。

注意输出时不要用%lf,用%f。(听说这是一个未定义行为)

参考代码

#include<cstdio>
#include<algorithm>
using namespace std;typedef long long ll;
const int Maxn=3e5;int N;
ll A[Maxn+5];
double ans1,ans2;int main() {freopen("pareto.in","r",stdin);freopen("pareto.out","w",stdout);scanf("%d",&N);ll sum=0,tot=0;for(int i=1;i<=N;i++) {scanf("%lld",&A[i]);sum+=A[i];}sort(A+1,A+N+1);reverse(A+1,A+N+1);for(int i=1;i<=N;i++) {tot+=A[i];double t1,t2;t1=100.0*i/N,t2=100.0*tot/sum;if((t2-t1)>(ans2-ans1))ans1=t1,ans2=t2;}printf("%f\n%f\n",ans1,ans2);return 0;
}

Unija

题目翻译

分析

不难发现每个象限内的面积都是一样的,所以我们可以只求第一象限的面积,将这个值乘4即可得到答案。

这样原本不整齐的边变得整齐了,这样更容易计算了。

那么我们考虑离散化+线段树,似乎空间和时间都很卡。。。

只有考虑扫描了。

我们将所有矩形按yyy值进行排序,再记录一个当前的最大值mmm,当一个矩形的xix_ixi​小于mmm时,这个矩形位于之前的矩形中,否则则在此矩形之外,我们这时就需要加上这多出来的部分,并更新mmm。

参考代码

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;typedef long long ll;
const int Maxn=1e6;struct Matrix {ll x,y;
}M[Maxn+5];
int N;
bool cmp(const Matrix &lhs,const Matrix &rhs) {return lhs.y>rhs.y;}int main() {freopen("unija.in","r",stdin);freopen("unija.out","w",stdout);scanf("%d",&N);for(int i=1;i<=N;i++) {scanf("%lld %lld",&M[i].x,&M[i].y);M[i].x/=2,M[i].y/=2;}sort(M+1,M+N+1,cmp);ll maxx=0;ll ans=0;for(int i=1;i<=N;i++)if(maxx<M[i].x) {ans+=((M[i].x-maxx)*M[i].y);maxx=M[i].x;}printf("%lld\n",4*ans);return 0;
}

Ronald

题目翻译

分析

简要分析可知,要想得到一个完全图,那么最后一步操作中所选的点,必须是与图中任何一个其他的点没有连接,且其他的点都相互连接的。

但我们没有办法从这个结论入手。我们换个方向,从最开始选的点入手。

那么我们考虑强制111号点为最先选的点。

接下来说明这个方法的正确性:

由于两城市之间的航线在选其中一个时都会发生改变,所以,这条航线是否存在取决于Krump的操作次数,故我们可以限定每个城市要么不选,要么只选一次。

那么对于城市111,我们有两种选择:开始不选,开始选一次。那么对于两种选择,我们都可以检查它是否是一个完全图。对于其他任何一个城市,我们都可以通过选它来增加它到111的航线。我们这样就可以贪心地选择所有其他的点,并最后判断是否是一个完全图即可。

还有一个结论:若答案是DA,则图中有且只有两个连通块且这两个连通块是完全的。

我没有证出来。。。

参考代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;const int Maxn=1000;int N,M;
bool G[Maxn+5][Maxn+5];
bool tmp[Maxn+5][Maxn+5];
bool vis[Maxn+5];void Filp(bool g[][Maxn+5],int u) {for(int i=1;i<=N;i++)if(i!=u)g[u][i]=g[i][u]=(!g[u][i]);
}
bool Check(bool g[][Maxn+5]) {for(int i=2;i<=N;i++)if(!g[1][i])Filp(g,i);for(int i=1;i<=N;i++)for(int j=i+1;j<=N;j++)if(g[i][j]==false)return false;return true;
}int main() {freopen("ronald.in","r",stdin);freopen("ronald.out","w",stdout);scanf("%d %d",&N,&M);for(int i=1;i<=M;i++) {int u,v;scanf("%d %d",&u,&v);G[u][v]=G[v][u]=true;}memcpy(tmp,G,sizeof tmp);Filp(tmp,1);puts(Check(tmp)||Check(G)?"DA":"NE");return 0;
}

Poklon

题目翻译

分析

莫队的板子题。。。直接写就是。。。注意题目要求的是恰好两次,故在增加或删减的时候只要出现次数达到3或1就答案减一。

参考代码

#include<cmath>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;const int Maxn=5e5;int N,Q,A[Maxn+5];
int Block;
vector<int> a;struct Query {int l,r,id;int ans;
};
bool cmp_query(Query lhs,Query rhs){return (lhs.l/Block==rhs.l/Block?lhs.r<rhs.r:lhs.l/Block<rhs.l/Block);}
bool cmp_getans(Query lhs,Query rhs){return lhs.id<rhs.id;}Query q[Maxn+5];
int cnt[Maxn+5],ans;void add(int pos) {cnt[A[pos]]++;if(cnt[A[pos]]==2)ans++;if(cnt[A[pos]]==3)ans--;
}
void del(int pos) {cnt[A[pos]]--;if(cnt[A[pos]]==2)ans++;if(cnt[A[pos]]==1)ans--;
}int main() {freopen("poklon.in","r",stdin);freopen("poklon.out","w",stdout);scanf("%d %d",&N,&Q);Block=sqrt(N);for(int i=1;i<=N;i++) {scanf("%d",&A[i]);a.push_back(A[i]);}sort(a.begin(),a.end());a.resize(unique(a.begin(),a.end())-a.begin());for(int i=1;i<=N;i++)A[i]=lower_bound(a.begin(),a.end(),A[i])-a.begin()+1;for(int i=1;i<=Q;i++) {scanf("%d %d",&q[i].l,&q[i].r);q[i].id=i;}sort(q+1,q+Q+1,cmp_query);int l=1,r=0;for(int i=1;i<=Q;i++) {while(l<q[i].l)del(l),l++;while(l>q[i].l)l--,add(l);while(r<=q[i].r)add(r),r++;while(r>q[i].r+1)r--,del(r);q[i].ans=ans;}sort(q+1,q+Q+1,cmp_getans);for(int i=1;i<=Q;i++)printf("%d\n",q[i].ans);return 0;
}

Strelice

题目翻译

分析

对于棋盘上的第一列的任意一个位置,我们可以暴力地处理出这条路径上的起点和到最后一列的终点的路径,并将它们都画在图上。

我们把最后一列看成一个点的话,那么,很显然的,整张图就成了一棵树。我们称此时的第一列的所有点为叶子节点。

对于每一个叶子,我们将它们从上至下地标号;对于每一个非叶子节点,我们记录下若将它涂色,那它能覆盖的叶子节点编号区间,即从这些叶子节点出发能够经过这个点,因为我们很容易知道这个棋盘上路径是不会交叉的。

但有些叶子节点是无法走到最后一列的,这些点,以及通过这些点能够走到的点,对于答案是有贡献的(因为我们要求恰好覆盖)。我们可以把这些点用来凑数。

通过以上的操作,我们将这个问题变成了一个集合覆盖问题,这个问题我们用DP解决。

记sx,ys_{x,y}sx,y​为选坐标为(x,y)(x,y)(x,y)的点时,这个点能够覆盖的最小的叶子节点编号,tx,yt_{x,y}tx,y​为选(x,y)(x,y)(x,y)时能覆盖到的最大叶子节点编号。

那么定义状态f[i][j]f[i][j]f[i][j]为选出jjj个节点,使这些点恰好覆盖了编号小于等于iii的叶子节点。

不难得出状态转移方程:f[tx,y][j+1]=f[tx,y][j+1]∨f[sx,y][j]f[t_{x,y}][j+1]=f[t_{x,y}][j+1]\vee f[s_{x,y}][j]f[tx,y​][j+1]=f[tx,y​][j+1]∨f[sx,y​][j]

这是一个求可行性的状态转移方程,我们必须在转移时记录路径。

最后找出一些能够恰好覆盖有用的叶子节点的节点,加上一些凑数的节点,凑齐KKK个点即可。

由于我们不可能开一个map来存储这些点的所有s,ts,ts,t与树形图,所以我们必须将坐标压成一个S−1S-1S−1进制数,即(x,y)(x,y)(x,y)表示成1+x(S−1)+y1+x(S-1)+y1+x(S−1)+y。(用000号点表示最后一列的所有节点)

注意由于点数最多只能涂上R(S−1)R(S-1)R(S−1)个,所以我们要特判一下。

参考代码

#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;typedef pair<int,int> pii;
const int Maxsize=1e6;
const int Maxk=50;int N,M,K;
char str[Maxsize+5];
vector<int> G[Maxsize+5];
bool leaf[Maxsize+5];inline int ID(int x,int y){return (y==M-1?0:(1+x*(M-1)+y));}
inline pii Inv(int p){return make_pair((p-1)/(M-1),(p-1)%(M-1));}bool vis[Maxsize+5];
int cnt;
vector<pii> pth[Maxsize+5];
int s[Maxsize+5],t[Maxsize+5];void DFS(int u,bool in_path) {vis[u]=true;s[u]=cnt;if(leaf[u])cnt++;for(int i=0;i<(int)G[u].size();i++) {int v=G[u][i];if(vis[v])continue;DFS(v,in_path|leaf[u]);}t[u]=cnt;if(in_path==false&&u!=0&&s[u]!=t[u])pth[s[u]].push_back(make_pair(u,t[u]));
}bool f[Maxsize+5][Maxk+5];
int pnt[Maxsize+5][Maxk+5];int main() {freopen("strelice.in","r",stdin);freopen("strelice.out","w",stdout);scanf("%d %d %d",&N,&M,&K);if(N*(M-1)<K) {puts("-1");return 0;}for(int i=0;i<N;i++) {scanf("%s",str);for(int j=0;j<M-1;j++) {int pos=ID(i,j);if(j==0)leaf[pos]=true;char ch=str[j];if(ch=='R')G[ID(i,j+1)].push_back(pos);if(ch=='L')G[ID(i,j-1)].push_back(pos);if(ch=='D')G[ID(i+1,j)].push_back(pos);if(ch=='U')G[ID(i-1,j)].push_back(pos);}}DFS(0,false);vector<pair<int,int> > unused;for(int i=1;i<=N*(M-1);i++) {if(vis[i]==false)unused.push_back(Inv(i));else if(s[i]==t[i])unused.push_back(Inv(i));}f[0][0]=true;for(int i=0;i<cnt;i++)for(int tmp=0;tmp<(int)pth[i].size();tmp++) {pii j=pth[i][tmp];for(int k=0;k<K;k++)if(f[i][k]) {f[j.second][k+1]=true;pnt[j.second][k+1]=j.first;}}for(int i=0;i<=K;i++)if(f[cnt][i]&&i+(int)unused.size()>=K) {vector<pii> ans;for(int j=cnt;j;) {ans.push_back(Inv(pnt[j][i]));j=s[pnt[j][i]],i--;}while((int)ans.size()<K) {ans.push_back(unused.back());unused.pop_back();}for(int j=0;j<(int)ans.size();j++)printf("%d %d\n",ans[j].first+1,ans[j].second+1);return 0;}puts("-1");return 0;
}

COCI 2016/2017 Round #5题解相关推荐

  1. COCI 2016/2017 Round #3 题解

    COCI 2016/2017 Round #3 这套题代码量似乎有些大呀...前五题代码都已经破4KB了... 而且还要卡空间.卡常数... Imena 题目翻译 分析 细节模拟题,注意可能会出现名字 ...

  2. [赛后总结]COCI2016/2017 Round#3题解

    文章目录 Imena 题面 描述 输入 输出 分数分布 题解 实现 Pohlepko 题面 描述 输入 输出 分数分布 题解 实现 Kronican 题面 描述 输入 输出 分数分布 题解 实现 Kv ...

  3. [赛后总结]COCI2016/2017 Round#2题解

    文章目录 Go 题面 描述 输出 分数分布 题解 实现 Tavan 题面 描述 输入 输出 分数分布 题解 实现 Nizin 题目 描述 输入 输出 分数分布 题解 实现 Prosjecni 题目 描 ...

  4. 解题报告(一)D、(CROC 2016 - Final Round C)Binary Table(矩阵 + 状态压缩 + FWT)(3.5)

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  5. Macbook pro 2016/2017 接入扩展坞时断 WIFI 问题的解决办法

    Macbook pro 2016/2017 接入扩展坞时断 WIFI 问题的解决办法 参考文章: (1)Macbook pro 2016/2017 接入扩展坞时断 WIFI 问题的解决办法 (2)ht ...

  6. 百度2016/2017秋招部分题目解析

    今天把百度2016/2017秋招剩余的4星题目,以及少部分有难度或者比较有趣味的3星题目来一起分析下,所以这次就来个合集了(共包含了4个题目),总体来看题目比较简单,所以分析也会写得相对简略一些.尽管 ...

  7. 2017上半年计算机教学计划,2016—2017学年度第二学期信息技术教学计划

    2016-2017学年度第二学期信息教学计划 小学信息教学是一门极为重要的课程,顺应了时代需求,从小就要开始接触这门课程,才会适应社会的发展进步,开始肯定有点困难,但是希望大家能够保持学好的决心,能够 ...

  8. 哈师大计算机学院2016级新生,【通知公告】哈尔滨师范大学2016—2017学年度国家励志奖学金获奖学生初审名单公示...

    原标题:[通知公告]哈尔滨师范大学2016-2017学年度国家励志奖学金获奖学生初审名单公示 按照黑龙江省学生资助管理中心<关于上报2017年秋季高校奖学金评审等相关材料的通知>(黑教助中 ...

  9. Educational Codeforces Round 95题解

    Educational Codeforces Round 95题解 题目链接 代码链接 A. Buying Torches 题目大意: 你手上现在有一个木棍.有以下两种交换方式: 1.用一个木棍交换x ...

最新文章

  1. 历届奥运会中国金牌数
  2. QT的QSyntaxHighlighter类的使用
  3. 破解面试难题8个角度带你解读SQL面试技巧!
  4. 服务器,linux系统配置端口号的坑!!!服务器防火墙配置!!!
  5. 对HttpClient的理解
  6. 世界主要城市地铁地图
  7. 包含h3c、cisco、F5、华为、中兴、juniper等网络设备巡检命令整理,建议点赞收藏
  8. 决策支持系统(DSS)
  9. 用android手机测量身高,教你如何使用小米手机测量自己的身高!
  10. win10wifi开关自动弹回_win10突然搜不到wifi了,这个开关点不动,点了会自动变回去...
  11. android studio在夜神上打开_Android Studio 调用夜神模拟器
  12. 【PyG 教程】PyG 自定义构造 GNN
  13. KECRS: Towards Knowledge-Enriched Conversational Recommendation System
  14. Vue与React的异同
  15. 微信 Android 模块化架构重构实践
  16. 建行浙江分行总部【等。。。】
  17. 论文阅读笔记- Dremel
  18. 分享107个PHP源码,总有一款适合您
  19. centos7下zeppelin安装配置
  20. LightGBM整理

热门文章

  1. 【转帖】利用wsdl4j解析WSDL文件
  2. 茶室app开发为企业打造一个综合的共享经济服务平台
  3. 开发DBA在做什么?
  4. Log4j日志的级别与使用
  5. 怎么不让计算机不自动装驱动,收藏!不会装驱动怎么办?看这篇就可以了!
  6. CFLAGS、CXXFLAGS和LDFLAGS、LIBS和-L、-rpath、-rpath-link和LD_LIBRARY_PATH
  7. 量化交易Python实用功能函数(2)
  8. 黑龙江省09年计算机交企业网络搭建及应用答案,[计算机软件及应用]企业网络搭建及应用.pdf...
  9. amazon白皮书学习 II
  10. 关于 ASPICE 的理解