【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
8
10
3
11
1

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
3 0
5 0
NN
NWWWWWN

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
0 0
0 10
1 10
1 0

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 3 6
3 2
1 1
2 1

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 综合性测试的更多相关文章

  1. [SinGuLaRiTy] 2017-03-30 综合性测试

    [SinGuLaRiTy-1014] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 对于所有的题目:Time Limit:1s  |  Me ...

  2. [SinGuLaRiTy] 2017-03-27 综合性测试

    [SinGuLaRiTy-1013] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 这是 三道 USACO 的题...... 第一题:奶牛飞 ...

  3. [SinGuLaRiTy] 2017-07-26 综合性测试

    [SinGuLaRiTy-1032] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved.               单词 (word) 题目描述 ...

  4. [SinGuLaRiTy] 2017-04-08 综合性测试

    [SinGuLaRiTy-1016] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 对于所有的题目:Time Limit:1s  |  Me ...

  5. [SinGuLaRiTy] 2017 百度之星程序设计大赛-资格赛

    [SinGuLaRiTy-1034] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 度度熊保护村庄  Time Limit: 2000/10 ...

  6. [SinGuLaRiTy] 树形存储结构阶段性测试

    [SinGuLaRiTy-1011] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. G2019级信息奥赛专项训练 题目 程序名 时间 内存 ...

  7. 2017年IT行业测试调查报告

    在刚刚过去的2017年, 我们来一起看一下2017年IT行业测试调查报告 还是1到5名测试工程师最多 Test Architects 在北上广一线城市已经出现 https://www.lagou.co ...

  8. 日本IT行业劳动力缺口达22万 在日中国留学生迎来就业好时机 2017/07/18 11:25:09

    作者:倪亚敏 来源:日本新华侨报 发布时间:2017/07/18 11:25:09     据日本政府提供的数据,日本2018年应届毕业生的“求人倍率”已经达到了1.78倍.换言之,就是100名大学生 ...

  9. 2017/11/21 Leetcode 日记

    2017/11/21 Leetcode 日记 496. Next Greater Element I You are given two arrays (without duplicates) num ...

随机推荐

  1. Angular5学习笔记 - 虚拟RestfulApi配置与使用(六)

    一.安装json-server功能 #windows cnpm install json-server -g #Mac & Linux sudo npm install json-server ...

  2. 正确设置Linux的ulimit值的方法

    学习swoole的时候有一个max_conn参数, max_conn 描述:服务器允许维持的最大TCP连接数 说明:设置此参数后,当服务器已有的连接数达到该值时,新的连接会被拒绝.另外,该参数的值不能 ...

  3. c# OrderBy 实现List升序降序

    本文转载自:http://blog.csdn.net/chadcao/article/details/8730132 1)前台代码 <%@ Page Language="C#" ...

  4. [转] Linux 查找文件内容

    Linux查找文件内容的常用命令方法. 从文件内容查找匹配指定字符串的行: $ grep "被查找的字符串" 文件名例子:在当前目录里第一级文件夹中寻找包含指定字符串的.in文件g ...

  5. LINUX必须记住的指令

    写在前面: 1,<你一定要知道的关于Linux文件目录操作的12个常用命令>是楼主收集的关于Linux文件目录操作最常用的命令,包括文件或目录的新建.拷贝.移动.删除.查看等,是开发人员操 ...

  6. C# 获取图片某像素点RGB565值

    Project Source Download: http://download.csdn.net/detail/mostone/6360007 [csharp] view plain copy pu ...

  7. CentOS 7.2 部署Rsync + Lsyncd服务实现文件实时同步/备份 (三)

    配置过程中遇到的错误与查看日志 以下错误是在服务正常开启的情况下发生的,请先查看服务是否正常启动. 一.错误 1. rsync: failed to set times on "." ...

  8. Qt opencv开发环境

    在.pro文件中添加 INCLUDEPATH += C:\opencv\build\include\ #头文件路径 C:\opencv\build\include\opencv\ C:\opencv\ ...

  9. WPA密码攻击宝典

    原则:密码以8-10位为主.11位仅限于当地手机号.一般人的多年用数字做密码的习惯和心理,先数 字.再字母,或数字.字母重复几遍,字符几乎全用小写,所以淘汰大写及"~!@#$%^&* ...

  10. a标签中href=""的几种用法(转)

    a标签中href=""的几种用法   标签: html / a标签 / javascript 46371 众所周知,a标签的最重要功能是实现超链接和锚点.而且,大多数人认为a标签最 ...