[SinGuLaRiTy] 2017-07-21 综合性测试
【SinGuLaRiTy-1028】 Copyright (c) SinGuLaRiTy 2017. All Rights Reserved.
对于所有题目:Time Limit: 1s | Memory Limit: 256MB
[USACO2016 Jan] 愤怒的奶牛 (Angry Cows)
题目描述
在数轴x上摆放有n(2<=n<=50000)捆干草堆,没有任何两堆在同样的位置,所有的位置均为整数。你可以用弹弓射击射击数轴上的任意地点。如果你用弹弓以R的力度射击x处,那么该处会发生爆炸,爆炸的范围是以R为半径的圆形区域,所以它会使得[x-R,x+R]的所有干草堆同时发生爆炸。这些干草堆的爆炸半径是R-1。它们又会触发连锁反应,第三轮的爆炸的半径为R-2,依次递减。请选择最小的力度射击,使得所有的干草堆全部爆炸。
输入
第一行包含N。接下来N个整数,表示干草堆的位置。所有位置在[0,1000000000]内。
输出
输出最小的力度R,使得所有的干草堆发生爆炸。四舍五入保留一位小数。
样例数据
| 样例输入 | 样例输出 |
|
5 |
3.0 |
<样例解释>
如果以力度3射击坐标5,则坐标3,坐标8处的干草堆会发生爆炸,然后又会引爆坐标1和坐标10的干草堆,最后引爆坐标11处的干草堆。
解析
f[i]表示要炸掉i之前的所有干草堆,在i点最少需要的半径。
g[i]表示要炸掉i之后的所有干草堆,在i点最少需要的半径。
找到满足(j<i&&a[i]-a[j]>f[j]+1)的最后一个j,f[i]=min(a[i]-a[j],f[j+1]+1),g数组同理。
最后枚举起始的射击区间,计算答案。
由于答案的小数部分只可能是0或者0.5,所以将所有数乘以2就可以避免小数问题,最后答案再除以2就可以了。
Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm> #define ll long long
#define N 50005
#define inf 2000000000 using namespace std; int n,a[N],f[N],g[N]; int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
a[i]*=;
}
sort(a+,a+n+);
for(int i=;i<=n;i++)
f[i]=g[i]=inf;
int t=;
f[]=;
for(int i=;i<=n;i++)
{
while(t+<i&&a[i]-a[t+]>f[t+]+)
t++;
f[i]=min(a[i]-a[t],f[t+]+);
}
t=n;
g[n]=;
for(int i=n-;i>=;i--)
{
while(t->i&&a[t-]-a[i]>g[t-]+)
t--;
g[i]=min(a[t]-a[i],g[t-]+);
}
int ans=inf;
for(int i=,j=n;i<j;)
{
ans=min(ans,max((a[j]-a[i])/,max(f[i],g[j])+));
if(f[i+]<g[j-])
i++;
else
j--;
}
printf("%.1lf",(double)ans/);
return ;
}
[USACO2016 Jan] 无线电通信 (Radio Contact)
题目描述
农夫约翰和奶牛贝西要去寻找丢失的奶牛,为了彼此能联系对方,他们带着无线电通讯设备。不幸的是电池快没有电了。所以它们要尽量节省电能。农夫从位置(fx,fy)出发,一共走N步,贝西从位置(bx,by)出发,一共走M步。农夫的路线是由一个长度为N的字符串限制,字符串只出现’E’或’S’或’W’或’N’中,表示东南西北四个方向。农夫每一单位时间可以选择不动,或者按照限制走出一步。奶牛贝西也是如此。现在无线电设备每一单位时间消耗的电量等于他们的距离的平方。请问,他们走到终点,最少消耗多少电量?
输入
第一行两个整数n,m(1<=n,m<=1000),第二行为fx,fy表示农夫的起始位置,第三行为bx,by,表示贝西的起始位置。
接下来有两个字符串,第一个字符串表示农夫的路线,第二个字符串表示贝西的路线。
他们的坐标总是在(0<=x,y<=1000)。北是y的正方向,东为x的正方向。
输出
输出一个整数,表示最少消耗的电量。
样例数据
| 样例输入 | 样例输出 |
|
2 7 |
28 |
解析
其实,这是一道水题。
设f[i][j]表示当前第一个人走了i步第二个人走了j步,那么就有f[i+1][j]=min(f[i+1][j],f[i][j]+dis())。然后f[i][j+1]和f[i+1][j+1]用同样的方法推出来。
Code
#include<cstdio>
#include<iostream>
#include<cstring> #define N 1024 typedef long long ll; using namespace std; int n,m,a[N][],b[N][];
ll f[N][N];
char s[N]; inline int dis(int a,int b,int c,int d)
{
return (c-a)*(c-a)+(b-d)*(b-d);
} int main()
{
scanf("%d%d",&n,&m);
cin>>a[][]>>a[][]>>b[][]>>b[][];
scanf("%s",s+);
for(int i=;i<=n;i++)
{
if(s[i]=='N')
a[i+][]=a[i][],a[i+][]=a[i][]+;
else if(s[i]=='S')
a[i+][]=a[i][],a[i+][]=a[i][]-;
else if(s[i]=='W')
a[i+][]=a[i][]-,a[i+][]=a[i][];
else if(s[i]=='E')
a[i+][]=a[i][]+,a[i+][]=a[i][];
}
scanf("%s",s+);
for(int i=;i<=m;i++)
{
if(s[i]=='N')
b[i+][]=b[i][],b[i+][]=b[i][]+;
else if(s[i]=='S')
b[i+][]=b[i][],b[i+][]=b[i][]-;
else if(s[i]=='W')
b[i+][]=b[i][]-,b[i+][]=b[i][];
else if(s[i]=='E')
b[i+][]=b[i][]+,b[i+][]=b[i][];
}
for(int i=;i<=n+;i++)
for(int j=;j<=m+;j++)
f[i][j]=;
f[][]=;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
f[i+][j]=min(f[i+][j],f[i][j]+dis(a[i+][],a[i+][],b[j][],b[j][]));
f[i][j+]=min(f[i][j+],f[i][j]+dis(a[i][],a[i][],b[j+][],b[j+][]));
f[i+][j+]=min(f[i+][j+],f[i][j]+dis(a[i+][],a[i+][],b[j+][],b[j+][]));
}
printf("%I64d",f[n+][m+]);
return ;
}
[USACO2016 Jan] 熄灯 (Lights Out)
题目描述
谷仓是一个简单的多边形。它的每一条边或平行于x轴,或平行于y轴。从任意一个点沿顺时针方向走,横边和纵边是交替出现的。多边形一共有n个点,编号为1到n。其中1号点为出口。奶牛贝西已经完全记住了谷仓的地图。它从某一个点出发,只能沿着边界走,在开灯的情况,它能很快知道怎么走才能更快到达出口。可是有一天,灯熄灭了。它一下慌了神,然后它忘了自己在哪个点了。但是幸运的是它仍然记得整个谷仓的地图,而且它能够凭触觉知道当前点的内角有多大,它也能感觉到当前点是不是出口,而且经过一条边后也能精确地计算出该边的长度。现在,为了寻找出口,它决定采取这样的策略:沿着顺时针方向继续走下去,直到它能够判断出自己的位置,然后再选择距离最短的方向(顺时针或逆时针)走到出口。求最坏的情况下,贝西走到出口要比灯没坏的情况下多花多少时间。
输入
第一行包含N(4<=N<=200),接下来N行每行包含两个整数,表示多边形的n个顶点(xi,yi),按顺时针的方向给出。这些点的范围均在[-100000,100000]
输出
输出贝西按照上述策略在最坏情况下比正常情况下要多花的时间。
样例数据
| 样例输入 | 样例输出 |
|
4 |
2 |
<样例解释>

贝西如果在出口处(Point 1),肯定可以感知到,这绝对不会是最坏情况。现在考虑它在其他3个点时的情形:它当前可以感知到内角的大小。但因为内角都是90度,所以他无法确定自己位置。于是它按照既定的策略,顺时针走:
1.如果它在开始在点2,它需要走到点3,此时,它知道自己在哪里了。于是它找最短的路径,不管哪边,都是11.所以,它一共需要走12个单位。如果是开灯的情况下,只需要走10个单位。所以,它要多走两个单位。
2.如果它在点3,它要走11个单位。开灯的情况下也要走11个单位。
3.如果它在点4,它要走1个单位。开灯的情况下也要走1个单位。
于是最坏的情况下,它要多走两个单位。
解析
这道题,其实最重要的就是贝西判定当前的位置的方法:通过走过一段独一无二的路线。那么,我们怎么用代码进行实现呢?在这里,我用的是vector套pair,这样写也显得有些混乱;有一种用hash来判断的方法,相比之下还是好理解一点。(hash是一个很重要的东西,以后的字符串处理常常会用到) 大体思路就是通过用角度的大小(90度和270度)和边的长度来表达区分不同的路线,如果这个特征值一样,我们就认为贝西无法区分,也就找不到自己的位置;如果特征值不同,贝西就可以辨别出方向了。需要注意的是:数据的处理以及表达方式一定要确保能描述每一条路线的特征,而不会出现不同的路线有相同特征值的情况。
Code
#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
#include<cstdio> #define MAXN 210 using namespace std; int opt[MAXN]; int main()
{
int N;
scanf("%d",&N);
vector<pair<long long,long long> > A(N);
for(int i=;i<N;i++)
{
cin>>A[i].first>>A[i].second;
}
vector<int> S(,);
for(int i=;i<N;i++)
{
int j=(i+)%N;
int k=(i+)%N;
S.push_back(abs(A[i].first-A[j].first)+abs(A[i].second-A[j].second));
if((A[i].first-A[j].first)*(A[k].second-A[j].second)-(A[k].first-A[j].first)*(A[i].second-A[j].second)>)
S.push_back(-);
else
S.push_back(-);
}
S.back()=;
for(int i=;i<N;i++)
{
opt[i+]=opt[i]+S[i*+];
}
opt[N]=;
for(int i=N-;i>=;i--)
{
opt[i]=min(opt[i],opt[i+]+S[i*+]);
}
multiset<vector<int> > st;
for(unsigned int i=;i<S.size();i+=)
{
for(unsigned int ln=;i+ln<=S.size();ln+=)
{
st.insert(vector<int>(S.begin()+i,S.begin()+i+ln));
}
}
int result=;
for(unsigned int i=;i+<S.size();i+=)
{
int ln;
int cost=;
for(ln=;;ln+=)
{
if(st.count(vector<int>(S.begin()+i,S.begin()+i+ln))==)
break;
cost+=S[i+ln];
}
result=max(result,cost+opt[(i+ln)/]-opt[i/]);
}
cout<<result;
return ;
}
[Vijos 1157] 分梨子
题目描述
Finley家的院子里有棵梨树,最近收获了许多梨子。于是,Finley决定挑出一些梨子,分给幼稚园的宝宝们。可是梨子大小味道都不太一样,一定要尽量挑选那些差不多的梨子分给孩子们,那些分到小梨子的宝宝才不会哭闹。每个梨子都具有两个属性值,Ai和Bi,本别表示梨子的大小和甜度情况。假设在选出的梨子中,两个属性的最小值分别是A0和B0。只要对于所有被选出的梨子i,都满足C1*(Ai-A0)+C2*(Bi-B0)≤C3(其中,C1、C2和C3都是已知的常数),就可以认为这些梨子是相差不多的,可以用来分给小朋友们。那么,作为幼稚园园长的你,能算出最多可以挑选出多少个梨子吗?
输入
第一行一个整数N(1≤N≤2000),表示梨子的总个数。 第二行三个正整数,依次为C1,C2和C3(C1,C2≤2000,C3≤10^9)。 接下来的N行,每行两个整数。第i行的两个整数依次为Ai和Bi。
输出
只有一个整数,表示最多可以选出的梨子个数。
样例数据
| 样例输入 | 样例输出 |
|
3 |
2 |
解析
神奇的题~
对于这道题,我们要采用"数形结合"的思想:每一个梨子不是有两个特征值Ai和Bi吗,我们要把它们看做一组坐标(Ai,Bi),这样一来,每个梨子就变为了坐标轴上的一个点。我们来继续处理给出的题目信息:在选出的梨子里,有两个最小值,也就是说,对于所有我们选中的梨子,都满足:Ai>A0,Bi>B0,也就是说,所有的我们选中的梨子所代表的的点,都应该位于直线x=A0的右边,直线y=B0的上方。<是不是很"神奇"?>我们继续,题目又说了:每一个梨子(点)都满足C1*(Ai-A0)+C2*(Bi-B0)≤C3,我们用更"数学"的语言翻译一下,就变成:“每一个点(X,Y)都满足M*(X-a)+N(Y-b)≤C (M,N,C均为常数,我们在这里也暂且把a和b当做常数)”,嘿,这不是高中数学教材里的线性规划不等式吗?下面我们来画一画图(图中的点代表梨子):

如图,三条直线围成的这个直角三角形内的点就是我们能够选择的梨子了。欢呼了?雀跃啦?不行,现在直接枚举A0、B0,就已经是O(n^2)了,然后再在三角形里面扫描满足条件的梨子,O(n^3)直接超时。于是乎,我们要想一个法子,让扫描梨子这一项的工程量减小一点。我们先将原来的不等式变为:C1Ai+C2Bi-C3<=C1A0+C2B0 。然后我们可以这么搞:先在外层来一个for循环确定A0,接下来我们再由低到高枚举B0,这时看一看我们刚刚得出的不等式,发现等式右边的值变大了,也就是说会有新的梨子满足这个不等式。——哎,有法子了!我们在枚举A0、B0之前预处理一下:1>记录每一个y轴(y=1,y=2,y=3......)上的梨子(点)的数量,2>将梨子(点)按C1Ai+C2Bi-C3排序。我们在枚举B0的过程中,先删去由于B0增大而从三角形下方剔除出去的梨子(由于有了<1>预处理,这个过程就是O(1)的了),再加上新的满足不等式的值(<2>预处理也大大见减少了时间),不断更新,然后取最大值,最后就能得到答案了。
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std; const int MAXN=;
struct node
{
int a,b,s;
}p[MAXN];
int c1,c2,c3;
int ans;
int n; inline bool cmp(const node&a,const node&b)
{
return a.s<b.s;
} void init()
{
scanf("%d",&n);
scanf("%d%d%d",&c1,&c2,&c3);
for(int i=;i<=n;i++)
{
scanf("%d%d",&p[i].a,&p[i].b);
p[i].s=p[i].a*c1+p[i].b*c2;
}
} int main()
{
init();
sort(p+,p+n+,cmp);
for(int i=;i<=n;i++)
{
int a0=p[i].a; int b0=p[i].b; int cur=i;
int tot=;
while(p[cur++].s<=c1*a0+c2*b0+c3&&cur<=n)
tot++;
ans=max(ans,tot);
}
cout<<ans<<endl;
return ;
}
Time: 2017-07-21
[SinGuLaRiTy] 2017-07-21 综合性测试的更多相关文章
- [SinGuLaRiTy] 2017-03-30 综合性测试
[SinGuLaRiTy-1014] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 对于所有的题目:Time Limit:1s | Me ...
- [SinGuLaRiTy] 2017-03-27 综合性测试
[SinGuLaRiTy-1013] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 这是 三道 USACO 的题...... 第一题:奶牛飞 ...
- [SinGuLaRiTy] 2017-07-26 综合性测试
[SinGuLaRiTy-1032] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 单词 (word) 题目描述 ...
- [SinGuLaRiTy] 2017-04-08 综合性测试
[SinGuLaRiTy-1016] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 对于所有的题目:Time Limit:1s | Me ...
- [SinGuLaRiTy] 2017 百度之星程序设计大赛-资格赛
[SinGuLaRiTy-1034] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 度度熊保护村庄 Time Limit: 2000/10 ...
- [SinGuLaRiTy] 树形存储结构阶段性测试
[SinGuLaRiTy-1011] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. G2019级信息奥赛专项训练 题目 程序名 时间 内存 ...
- 2017年IT行业测试调查报告
在刚刚过去的2017年, 我们来一起看一下2017年IT行业测试调查报告 还是1到5名测试工程师最多 Test Architects 在北上广一线城市已经出现 https://www.lagou.co ...
- 日本IT行业劳动力缺口达22万 在日中国留学生迎来就业好时机 2017/07/18 11:25:09
作者:倪亚敏 来源:日本新华侨报 发布时间:2017/07/18 11:25:09 据日本政府提供的数据,日本2018年应届毕业生的“求人倍率”已经达到了1.78倍.换言之,就是100名大学生 ...
- 2017/11/21 Leetcode 日记
2017/11/21 Leetcode 日记 496. Next Greater Element I You are given two arrays (without duplicates) num ...
随机推荐
- 最小LINUX系统下U盘的挂载及卸载
U盘挂载命令U盘插入的时候会显示启动信息,启动信息中sda: sda1指U盘的设备名为sda1dev设备目录下有一个sda1设备文件,此设备文件就是我们插入的U盘,我们将这个设备文件挂载到Linux系 ...
- wp8安装SSL证书
把证书打成zip包,wp8的IE能下载并打开ZIP包,然后点击cer文件,就能安装证书了
- PhoneGap应用图标icon和启动页面SplashScreen
app/config.xml <icon gap:platform="android" gap:qualifier="ldpi" src="re ...
- Drools学习笔记4—Consequence/RHS
Right Hand Side,当LHS所有条件满足才会执行 可以使用LHS部分定义的绑定变量.全局变量.或者直接编写JAVA代码. 提供宏函数操作working memory fact对象,如ins ...
- PHP实现常用排序算法(含示意动图)
目录 1 快速排序 2 冒泡排序 3 插入排序 4 选择排序 5 归并排序 6 堆排序 7 希尔排序 8 基数排序 总结 作为phper,一般接触算法的编程不多. 但基本的排序算法还是应该掌握. 毕竟 ...
- 11-04 SQLserver基础--连接查询、联合查询、索引
一.子查询补充: Exists的用法: select*from haha where exists(select*from bumen where bumen.code=haha.bumen,and ...
- 【转】Android下面打印进程函数调用堆栈(dump backtrace)的方法
1. 为什么要打印函数调用堆栈? 打印调用堆栈可以直接把问题发生时的函数调用关系打出来,非常有利于理解函数调用关系.比如函数A可能被B/C/D调用,如果只看代码,B/C/D谁调用A都有可能,如果打印出 ...
- ARQ
自动重传请求(Automatic Repeat-reQuest,ARQ)是OSI模型中数据链路层和传输层的错误纠正协议之一.它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输.如果 ...
- SQL基础E-R图基础
ER图分为实体.属性.关系三个核心部分.实体是长方形体现,而属性则是椭圆形,关系为菱形. ER图的实体(entity)即数据模型中的数据对象,例如人.学生.音乐都可以作为一个数据对象,用长方体来表示, ...
- HDU 6396(2018多校第七场1011) Swordsman
场上场下各种TLE到怀疑人生...经过大佬指点之后才知道要用fread才能过,一般的快读不行... 题意:一个剑客打小怪兽,有n头小怪兽,剑客和小怪兽有m个属性.只有剑客的m个属性都大于等于某个小怪兽 ...