US Open 2016 Contest
比较弱,只写了金组和银组,铂金组的第一题。
【262144】
http://www.usaco.org/index.php?page=viewproblem2&cpid=648
给一个序列,相邻两个数组相同的可以合并变成数值大一的数,问最大能得到的数。n<262144,val<=40
是金组某道题的升级版。
因为val<40,实际上最大可以取到的不超过60.所以从1-60,看看从i开始是否能合并到当前数值。可以的话记录合并到哪一位。
初始化f[i][val[i]]=i+1,状态转移f[i][j]=f[f[i][j-1][j-1]。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
#include<stack>
#include<cmath>
#include<vector>
#include<map>
#define maxn 300000
using namespace std; int f[][maxn],num[maxn],ans,n; void input() {freopen("262144.in","r",stdin);freopen("262144.out","w",stdout);}
void output() {fclose(stdin);fclose(stdout);}
void work()
{
int i,k;
memset(f,,sizeof(f));
for (k=;k<=;k++) {
for (i=;i<=n;i++) {
if (num[i]==k) f[k][i]=i+;
else {
if (!k || !f[k-][i] || !f[k-][f[k-][i]]) f[k][i]=;
else f[k][i]=f[k-][f[k-][i]];
}
if (f[k][i]) ans=k;
}
f[k][n+]=;
}
return;
} int main()
{
input();
scanf("%d\n",&n);
int i;
for (i=;i<=n;i++) scanf("%d",&num[i]);
work();
printf("%d\n",ans);
output();
return ;
}
262144
AU
【Splitting the Field】
http://www.usaco.org/index.php?page=viewproblem2&cpid=645
在平面内给一些点,然后用两个矩形把所有的点围起来,矩形不能有交集和重边,问最小面积。N≤50,000
首先,两个矩形必定会在最左最右最上最下。进一步可以发现,答案一定在左右分割或者上下分割两种情况里面。
然后就排好序,扫一边求以这个点为分界划出的两个区域的面积。
两个答案取最大值。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
#include<stack>
#include<cmath>
#include<vector>
#include<map>
#define LL long long
#define maxn 100000
using namespace std; struct node{LL x,y;} point[maxn];
LL nmax[maxn],nmin[maxn];
int n; int cmp1(node p1,node p2){return p1.y<p2.y;}
int cmp2(node p1,node p2){return p1.x<p2.x;} void input() {freopen("1.in","r",stdin);freopen("1.out","w",stdout);}
void output() {fclose(stdin);fclose(stdout);}
int main()
{
input();
scanf("%d",&n);
int i;
for (i=;i<n;i++) scanf("%lld %lld",&point[i].x,&point[i].y);
LL ans=((LL)()<<),now1,now2,now,big1,big2;
//x
// printf("\n");
sort(point,point+n,cmp1);
big1=point[n-].y-point[].y;
nmax[n-]=point[n-].x;
nmin[n-]=point[n-].x;
for (i=n-;i>=;i--) {
nmax[i]=max(point[i].x,nmax[i+]);
nmin[i]=min(point[i].x,nmin[i+]);
}
// for (i=0;i<n;i++) printf("%lld %lld %lld %lld\n",point[i].x,point[i].y,nmin[i],nmax[i]);
now1=point[].x;
now2=point[].x;
for (i=;i<n-;i++) {
now1=max(point[i].x,now1);
now2=min(point[i].x,now2);
if (point[i+].y!=point[i].y) {
now=(point[i].y-point[].y)*(now1-now2)
+(point[n-].y-point[i+].y)*(nmax[i+]-nmin[i+]);
if (now<ans) ans=now;
}
}
// printf("%lld %d\n",ans,ans1);
//y
// printf("\n");
sort(point,point+n,cmp2);
big2=point[n-].x-point[].x;
nmax[n-]=point[n-].y;
nmin[n-]=point[n-].y;
for (i=n-;i>=;i--) {
nmax[i]=max(point[i].y,nmax[i+]);
nmin[i]=min(point[i].y,nmin[i+]);
}
// for (i=0;i<n;i++) printf("%lld %lld %lld %lld\n",point[i].x,point[i].y,nmin[i],nmax[i]);
now1=point[].y;
now2=point[].y;
for (i=;i<n-;i++) {
now1=max(point[i].y,now1);
now2=min(point[i].y,now2);
if (point[i+].x!=point[i].x) {
now=(point[i].x-point[].x)*(now1-now2)
+(point[n-].x-point[i+].x)*(nmax[i+]-nmin[i+]);
if (now<ans) ans=now;
}
} // printf("%lld %d\n",ans,ans1);
printf("%lld\n",big1*big2-ans);
output();
return ;
}
split
【Closing the Farm】
http://www.usaco.org/index.php?page=viewproblem2&cpid=646
给一个图,每次去掉一个点,问每次去掉后余下的图是否联通。
倒过来,变成每次加一个点看是否图联通。并查集做就可以。
(并查集加了启发式合并然并卵)
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
#include<stack>
#include<cmath>
#include<vector>
#include<map>
#define maxn 201000
#define maxm 401000
using namespace std; int to[maxm],next[maxm],first[maxn],ans[maxn],fa[maxn],rank[maxn],chose[maxn],num[maxn],n,m,total=; void input() {freopen("closing.in","r",stdin);freopen("closing.out","w",stdout);}
void output() {fclose(stdin);fclose(stdout);}
void addedge(int j,int k)
{
next[++total]=first[j];
to[first[j]=total]=k;
}
int find(int x)
{
if (fa[x]==x) return x;
return fa[x]=find(fa[x]);
} int main()
{
input();
int i,j,k;
scanf("%d %d",&n,&m);
memset(first,,sizeof(first));
for (i=;i<=m;i++) {
scanf("%d %d",&j,&k);
addedge(j,k);
addedge(k,j);
}
for (i=;i<=n;i++) scanf("%d",&num[i]);
int now=;
for (i=;i<=n;i++) fa[i]=i;
memset(chose,,sizeof(chose));
memset(ans,,sizeof(ans));
memset(rank,,sizeof(rank));
for (i=n;i;i--) {
++now;
int x=num[i];
chose[x]=;
rank[x]=;
for (j=first[x];j;j=next[j]) {
int too=to[j];
if (chose[too]) {
int fy=find(too);
int fx=find(x);
if (fy!=fx) {
--now;
if (rank[fx]>rank[fy]) fa[fy]=fx;
else {
fa[fx]=fy;
if (rank[fx]==rank[fy]) rank[fy]++;
}
}
}
}
if (now==) ans[i]=;
}
for (i=;i<=n;i++)
printf(ans[i]?"YES\n":"NO\n");
output();
return ;
}
closing
【248】
262144的弱化版。n^3dp就可以了。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
#include<stack>
#include<cmath>
#include<vector>
#include<map>
#define maxn 300
using namespace std; int f1[maxn][maxn],f2[maxn][maxn],f3[maxn][maxn],num[maxn],ans=,n; void input() {freopen("1.in","r",stdin);freopen("1.out","w",stdout);}
void output() {fclose(stdin);fclose(stdout);}
void dfs(int ll,int rr)
{
if (f1[ll][rr]!=-) return;
if (ll==rr) {
f1[ll][rr]=num[ll];
f2[ll][rr]=num[ll];
f3[ll][rr]=num[ll];
ans=max(ans,f1[ll][rr]);
ans=max(ans,f2[ll][rr]);
ans=max(ans,f3[ll][rr]);
return;
}
if (ll+==rr) {
if (num[ll]==num[rr]) {
f1[ll][rr]=num[ll]+;
f2[ll][rr]=num[ll]+;
f3[ll][rr]=num[rr]+;
}
else {
f1[ll][rr]=;
f2[ll][rr]=num[ll];
f3[ll][rr]=num[rr];
}
ans=max(ans,f1[ll][rr]);
ans=max(ans,f2[ll][rr]);
ans=max(ans,f3[ll][rr]);
return;
}
f1[ll][rr]=;
for (int i=ll;i<rr;i++) {
dfs(ll,i);
dfs(i+,rr);
if (f1[ll][i]==f1[i+][rr] && f1[ll][i]) f1[ll][rr]=f1[ll][i]+;
if (f2[ll][i]>f2[ll][rr]) f2[ll][rr]=f2[ll][i];
if (f3[i+][rr]>f3[ll][rr]) f3[ll][rr]=f3[i+][rr];
if (f3[ll][i]==f2[i+][rr] && f2[i+][rr])
ans=max(ans,f2[i+][rr]+);
ans=max(ans,f1[ll][rr]);
ans=max(ans,f2[ll][rr]);
ans=max(ans,f3[ll][rr]);
}
} int main()
{
input();
scanf("%d",&n);
int i,j;
for (i=;i<=n;i++) scanf("%d",&num[i]);
for (i=;i<=n;i++)
for (j=i;j<=n;j++)
f1[i][j]=-;
dfs(,n);
// for (i=1;i<=n;i++)
// for (j=i;j<=n;j++)
// printf("%d %d:%d %d %d\n",i,j,f1[i][j],f2[i][j],f3[i][j]);
printf("%d\n",ans);
output();
return ;
}
248
ag
【Field Reduction】
给一些在平面内的点,去掉三个点,问余下的点用矩形圈起来的最小面积。
直接爆搜,每次只可能去最上最下最左最右的点。4^3。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
#include<stack>
#include<cmath>
#include<vector>
#include<map>
#define maxn 600000
using namespace std; struct node{int x,y,num;} point[maxn],po2[maxn];
int ans,n,numx[maxn],numy[maxn],chose[maxn],p[]; int cmp1(node x,node y){return x.x<y.x;}
int cmp2(node x,node y){return x.y<y.y;} void input() {freopen("1.in","r",stdin);freopen("1.out","w",stdout);}
void output() {fclose(stdin);fclose(stdout);}
void dfs(int x)
{
int l1=-,l2=n,r1=-,r2=n;
while (!chose[numx[++l1]]);
while (!chose[numx[--l2]]);
while (!chose[numy[++r1]]);
while (!chose[numy[--r2]]);
if (x==) {
// for (int i=0;i<3;i++) printf("%d ",p[i]);printf("\n");
// printf("%d %d %d %d %d %d %d\n",numx[l1],numx[l2],numy[r1],numy[r2],
// (po2[numx[l2]].x-po2[numx[l1]].x),
// (po2[numy[r2]].y-po2[numy[r1]].y),
// (po2[numx[l2]].x-po2[numx[l1]].x)*(po2[numy[r2]].y-po2[numy[r1]].y));
ans=min((po2[numx[l2]].x-po2[numx[l1]].x)*(po2[numy[r2]].y-po2[numy[r1]].y),ans);
return;
}
chose[numx[l1]]=;
p[x]=numx[l1];
dfs(x+);
chose[numx[l1]]=; chose[numx[l2]]=;
p[x]=numx[l2];
dfs(x+);
chose[numx[l2]]=; chose[numy[r1]]=;
p[x]=numy[r1];
dfs(x+);
chose[numy[r1]]=; chose[numy[r2]]=;
p[x]=numy[r2];
dfs(x+);
chose[numy[r2]]=;
} int main()
{
input();
scanf("%d",&n);
int i;
for (i=;i<n;i++) {
scanf("%d %d",&point[i].x,&point[i].y);
point[i].num=i;
po2[i]=point[i];
}
sort(point,point+n,cmp1);
for (i=;i<n;i++) numx[i]=point[i].num;
sort(point,point+n,cmp2);
for (i=;i<n;i++) numy[i]=point[i].num;
// for (i=0;i<n;i++) printf("%d ",numx[i]);printf("\n");
// for (i=0;i<n;i++) printf("%d ",numy[i]);printf("\n");
ans=(<<)-;
for (i=;i<n;i++) chose[i]=;
dfs();
printf("%d\n",ans);
output();
return ;
}
reduce
【Diamond Collector】
给一些数,从数中选取出两个集合,要求集合内的数差不超过给定值,问两个集合数字个数和最大?
队列就可以啦,出队为当前点和队头距离大于m。然后每次的答案为之前的最大值和当前队里面数的个数。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
#include<stack>
#include<cmath>
#include<vector>
#include<map>
#define LL long long
#define maxn 55000
using namespace std; int f[maxn],n,ans,num[maxn],m; void input() {freopen("1.in","r",stdin);freopen("1.out","w",stdout);}
void output() {fclose(stdin);fclose(stdout);}
int main()
{
input();
scanf("%d %d",&n,&m);
int i;
for (i=;i<n;i++) scanf("%d",&num[i]);
sort(num,num+n);
int l=,r=-,ans=,now=;
while (++r<n) {
while (num[r]-num[l]>m) {
if (f[l]>ans) ans=f[l];
l++;
}
f[r]=r-l+;
// printf("%d %d %d %d %d\n",l,r,num[r],f[r],ans);
if (now<ans+f[r]) now=ans+f[r];
}
// for (i=0;i<n;i++) printf("%d %d %d\n",i,num[i],f[i]);
printf("%d\n",now);
output();
return ;
}
diamond
【Closing the Farm】同上
US Open 2016 Contest的更多相关文章
- CH0601 Genius ACM【倍增】【归并排序】
0601 Genius ACM 0x00「基本算法」例题 描述 给定一个整数 M,对于任意一个整数集合 S,定义“校验值”如下: 从集合 S 中取出 M 对数(即 2∗M 个数,不能重复使用集合中的数 ...
- 2016 Multi-University Training Contest 2 D. Differencia
Differencia Time Limit: 10000/10000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tot ...
- 2016 Multi-University Training Contest 1 G. Rigid Frameworks
Rigid Frameworks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- 2016 Multi-University Training Contest 1
8/11 2016 Multi-University Training Contest 1 官方题解 老年选手历险记 最小生成树+线性期望 A Abandoned country(BH) 题意: 1. ...
- 2016 Multi-University Training Contest 2
8/13 2016 Multi-University Training Contest 2官方题解 数学 A Acperience(CYD)题意: 给定一个向量,求他减去一个 α(>=0)乘以 ...
- 2016 Multi-University Training Contest 3
5/11 2016 Multi-University Training Contest 3官方题解 2016年多校训练第三场 老年选手历险记 暴力 A Sqrt Bo(CYD) 题意:问进行多少次开根 ...
- 2016 Multi-University Training Contest 4
6/12 2016 Multi-University Training Contest 4官方题解 KMP+DP A Another Meaning(CYD) 题意: 给一段字符,同时给定你一个单词, ...
- 2016 Multi-University Training Contest 5
6/12 2016 Multi-University Training Contest 5 期望+记忆化DP A ATM Mechine(BH) 题意: 去ATM取钱,已知存款在[0,K]范围内,每一 ...
- 2016 Multi-University Training Contest 6
5/12 2016 Multi-University Training Contest 6 官方题解 打表找规律/推公式 A A Boring Question(BH) 题意: ,意思就是在[0,n] ...
随机推荐
- nexys4-DDR开发板数码管驱动-第二篇
1. 有这个板子使用的是Artix-7系列的XC7A100T-1CSG324C芯片.作为7系列中的一款FPGA,这个芯片的结构与Kintex-7和Virtex-7几乎一样.也配备了XADC.在Arti ...
- VS中添加新项 数据选项卡下没有ADO.NET实体数据模型解决方案
第一种:C:\ProgramData下面搜索EFTools找到你vs对应版本的EFTools.msi 先remove 然后再Install 重启电脑再看 第二种:如果意外地删除了 Visual Stu ...
- PostFix支持SMTP认证
安装cyrus-sasl yum -y install cyrus-sasl* 启动服务,开机启动 service saslauthd start chkconfig saslauthd on 配置p ...
- 初识java atomic
2018-8-19 昨天看到java.util.concurrent.atomic相关的文章,之前有过留意但并未去了解,正好有空学习一下.本人理解atomic包是concurrent子包,当是为并发所 ...
- 软件测试的基础-摘自《selenium实践-基于电子商务平台》
软件测试的方法 一.等价类划分法 等价类划分法是把所有可能的输入数据,即程序的输入域划分成若干部分(子集),然后从每一个子集中选取少量具有代表性的数据作为测试用例. 有两种不同的情况:有效等价和无效等 ...
- hackerrank Project Euler #210: Obtuse Angled Triangles
传送门 做出一个好几个星期屯下来的题目的感觉就是一个字: 爽! 上图的黄点部分就是我们需要求的点 两边的部分很好算 求圆的地方有一个优化,由于圆心是整数点,我们可以把圆分为下面几个部分,阴影部分最难算 ...
- 《Git学习指南》学习笔记(二)
第三章 提交究竟是什么 每次提交都会生成一个40位的散列值.只要知道散列值,我们就可以恢复到该次提交,这个操作也被称之为检出(checkout)操作. 访问权限与时间戳 Git会保存每个文件原有的访问 ...
- Python3 数据类型-列表
序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推. 索引如下图: 列表命名(list): 组成:使用[]括起来,并且 ...
- nginx 添加的配置信息
使用logrotate管理Nginx日志配置如下: [root@vm-10-129-93-51 nginx]# vi /etc/logrotate.d/nginx /letv/log/nginx/*. ...
- wwnjld第二轮迭代测试报告
1.引言 1.1测试报告目的 被测试报告为wwnjld小组我们的时间管理软件的第二轮迭代所写的软件测试报告.在经过本小组大家不懈的努力之下,我们小组第二轮迭代的产品终于新鲜出炉了.这次测试小组的主要成 ...