Wannafly每日一题 2.17
来源:互联网 发布:要开淘宝网店怎么弄 编辑:程序博客网 时间:2024/05/17 01:11
首先说明: 题解都是从 wannafly里面得到的。 详情请关注微信公众号:WannaflyUnion
http://codeforces.com/problemset/problem/725/F
#include<cstdio>#include<algorithm>#include<vector>#include<queue>#include<string.h>using namespace std;#define ll __int64/*分析:先手: 对a: +a1-b2-(+a2-b1) = a1-a2 +b1-a2 a2-a1 +b2-b1 对b: +b1-a2 -(b2-a1) = a1-a2 +b1-b2 后手:a2-a1 +b2-b1对每对照片分类:1 a1<=b2 && b1<=a2, 双方都想要选择后手,且 如果先手都没有收益,那不会选2a1+b1<=a2+b2, 即对于该对照片,双方的后手收益都好于先手收益,且必有a1>b2或b1>a2,即必有一方有正收益 ,如果不选则没收益,但先选仍有收益3 对于剩下的物体 排除了废物品 和 后手有利物品那么只剩下 先手有利的物品了?? 如果不仅让自己得分最多,且让对手最少一开始想的是a1-b2+a2-b1 = a1+a2 -(b1+b2) 。。。然后越想越复杂然而看了题解,似乎我们只需要注意a1+b1 ,按这个来作为条件,这样子就完成了上面的要求。真是神奇!还有个问题:对于一对牌:a1 b1a2 b2如果a 先手了,b不一定马上选b2 可以去选其他更有价值的,那么我们可以重新创建一对: a2 b2 0 0 */struct node{ int a1,b1,a2,b2; int t;}s[100005],f[100005];int mp[100005];bool operator<(node a,node b){ //从大到小排 return a.a1+a.b1<b.a1+b.b1;}int main() { //freopen("1.txt", "r", stdin); int n; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d %d %d %d",&s[i].a1,&s[i].b1,&s[i].a2,&s[i].b2); } priority_queue<node> q; ll suma,sumb; suma=sumb=0; for(int i=1;i<=n;i++){ if(s[i].a1<=s[i].b2 && s[i].b1<=s[i].a2) continue; if(s[i].a1+s[i].b1<=s[i].a2+s[i].b2){ if(s[i].b1>s[i].a2) suma+=s[i].a2,sumb+=s[i].b1; else if(s[i].a1>s[i].b2) suma+=s[i].a1,sumb+=s[i].b2; } else{ node cnt; cnt.a1=s[i].a1, cnt.b1=s[i].b1, cnt.a2=s[i].a2, cnt.b2=s[i].b2; cnt.t=1; q.push(cnt); } } int cnt=0; while(!q.empty()){ cnt++; node tmp=q.top(); q.pop(); if(cnt%2){ suma+=tmp.a1; } else sumb+=tmp.b1; if(tmp.t==1){ tmp.t=2; tmp.a1=tmp.a2; tmp.b1=tmp.b2; tmp.a2=0; tmp.b2=0; q.push(tmp); } } printf("%I64d\n",(ll)(suma-sumb) );return 0;}
http://codeforces.com/gym/100820
先来想想问题:
题目只给定 n,r,w,h 也就是说要自己去决定 v 和 x
分析:
h=1e9
所以排除dp了?? 但n 1e5
所以我们可以将所有点 最多分成 1e5层
且每一层我们都最多只能经过一个点(或者不经过)
矩形
—————— l
|
| h
两点之间能够到达: vy=v;
t=h/v; vx=l/t=l*v/h
vx>=l*v/h v/r>=l*v/h => l*r<=h => r<=h/l; 所以能够到达和v 一毛钱关系都没有,至于h,l,r 有关。
然而图论写到一半发现: 第i层的点不会只和i+1层的点建边,哇,和后面的所有的点都可能建边,心态有点崩
还是看题解了,唉:对于这种边数太多的处理方法:
从上面的推理我们可以知道当车子位于某个点的时候,在y轴上前进 h ,那么在x轴能在[-h/r,h/r]移动
由此可以做两条射线与赛道相交得到 a,b; 且无论在哪个位置,这两条射线的夹角永远不会变
所以下一个能到达的点 必须满足 对其做同样的射线 有交点A,B 必须满足 A>=a && B>=b
如图:A可以到达B、C ,但无法到达D 。
那么对a做排序,然后对b做LIS 最长不下降子序列。
这里注意下,因为 B可以=b,所以不一定递增
呵呵,说出来好像又尽然如此简单,真的菜!!!真的瓜皮
顺便说下,最长不下降子序列。用upper_bound 很方便解决,可见代码。
#include<cstdio>#include<algorithm>#include<vector>#include<queue>#include<string.h>using namespace std;#define ll __int64/**/ll n,r,w,h;struct node{ ll x,y; ll a,b; bool operator < ( const node x) { return a<x.a; }}f[100005];ll lis[100005];int main() { freopen("1.txt", "r", stdin); scanf("%I64d %I64d %I64d %I64d",&n,&r,&w,&h); for(int i=1;i<=n;i++){ scanf("%I64d %I64d",&f[i].x,&f[i].y); ll l1=f[i].x; ll l2=w-f[i].x; f[i].a=l1*r+f[i].y; //注意爆int啊 f[i].b=l2*r+f[i].y; } sort(f+1,f+n+1); lis[1]=f[1].b; int len=0; for(int i=1;i<=n;i++){ int pos=upper_bound(lis+1,lis+len+1,f[i].b)-lis; //upper很好的解决的不下降问题 if(pos>len) lis[++len]=f[i].b; else lis[pos]=f[i].b; } printf("%d\n",len);return 0;}
- Wannafly每日一题 2.17
- 12-30 Wannafly每日一题 Pretty Song
- Wannafly 每日一题 2016-12-26 KAOS 字典树
- 每日一题2
- 每日一题
- 每日一题12.20
- 每日一题
- Javascript每日一题
- 每日一题
- Mysql每日一题
- 每日一题-1
- 每日一题
- 每日一题A
- 每日一题A
- 每日一题5.31
- 每日一题C
- 每日一题D
- 每日一题G
- MySQL之数据库定义语言(DDL)
- 写HTML+CSS页面时遇到的坑
- Android音频焦点详解(下)——源码详解
- SOJ 1008
- Spring Boot 之web Filter --支持排序的使用扩展
- Wannafly每日一题 2.17
- CSS学习笔记
- 看learnopengl 教程 随手记录
- 面向对象的5个编码原则
- 浏览器主页被hao123劫持的解决办法
- 编译Spark-1.6.3源码--Maven工具
- electron的入门学习
- 在mac上为unity开发安装xamarin studio
- git