比较弱,只写了金组和银组,铂金组的第一题。

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的更多相关文章

  1. CH0601 Genius ACM【倍增】【归并排序】

    0601 Genius ACM 0x00「基本算法」例题 描述 给定一个整数 M,对于任意一个整数集合 S,定义“校验值”如下: 从集合 S 中取出 M 对数(即 2∗M 个数,不能重复使用集合中的数 ...

  2. 2016 Multi-University Training Contest 2 D. Differencia

    Differencia Time Limit: 10000/10000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tot ...

  3. 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) ...

  4. 2016 Multi-University Training Contest 1

    8/11 2016 Multi-University Training Contest 1 官方题解 老年选手历险记 最小生成树+线性期望 A Abandoned country(BH) 题意: 1. ...

  5. 2016 Multi-University Training Contest 2

    8/13 2016 Multi-University Training Contest 2官方题解 数学 A Acperience(CYD)题意: 给定一个向量,求他减去一个  α(>=0)乘以 ...

  6. 2016 Multi-University Training Contest 3

    5/11 2016 Multi-University Training Contest 3官方题解 2016年多校训练第三场 老年选手历险记 暴力 A Sqrt Bo(CYD) 题意:问进行多少次开根 ...

  7. 2016 Multi-University Training Contest 4

    6/12 2016 Multi-University Training Contest 4官方题解 KMP+DP A Another Meaning(CYD) 题意: 给一段字符,同时给定你一个单词, ...

  8. 2016 Multi-University Training Contest 5

    6/12 2016 Multi-University Training Contest 5 期望+记忆化DP A ATM Mechine(BH) 题意: 去ATM取钱,已知存款在[0,K]范围内,每一 ...

  9. 2016 Multi-University Training Contest 6

    5/12 2016 Multi-University Training Contest 6 官方题解 打表找规律/推公式 A A Boring Question(BH) 题意: ,意思就是在[0,n] ...

随机推荐

  1. OpenCV 3.2 FlannBasedMatcher

    #include <iostream> #include <string> #include <boost/timer.hpp> #include "op ...

  2. CLR via c#读书笔记八:泛型

    1.定义泛型类型或方法时,为类型指定的任何变量(比如T)都称为类型参数.使用泛型类型或方法时指定的具体数据类型称为类型实参. 2.System.Collections.Concurrent命名空间提供 ...

  3. 本地生成Rails API文档

    #新建一rails项目 rails new dummy cd dummy # 生成文档 rake doc:rails 剩下的就是等待了. 生成的文档在dummp/doc/api .浏览器打开index ...

  4. 【原创】MyEclipse反编译添加jadclipse_3.3.0 曲折的完美解决

    本人QQ:9715234 (java屌丝一枚) 共三部分 一.下载两个文件exe和jar 1.http://nchc.dl.sourceforge.net/project/jadclipse/jadc ...

  5. selenium自动化之显式等待和EC(expected_conditions)模块

    很多人都有这种经历,selenium脚本当前运行没问题,过了一段时间再运行就报错了,然后过几天又好了.其中的原因估计60%的人都知道,是因为元素加载这块有问题.通常的解决方案就是加上sleep或者隐式 ...

  6. Appium(Python)测试混血App

    Hybrid App(混合模式移动应用)是指介于web-app.native-app这两者之间的app兼具Native App良好用户交互体验的优势和Web App跨平台开发的优势 HybridApp ...

  7. 第一篇 Flask基础篇之(配置文件,路由系统,模板,请求响应,session&cookie)

    Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后 ...

  8. 关于wcf服务编译平台是x86, 运行平台是x64时,如何调试

    关于调试CTDC项目中的的 wcf服务时注意事项: 因为wcf项目引用的的 x86的程序集,所以wcf生成的目标平台为x86.故在64系统上调试需要执行下面的脚本 具体操作步骤: 1. 必须使用201 ...

  9. HDU 3007 Buried memory(计算几何の最小圆覆盖,模版题)

    Problem Description Each person had do something foolish along with his or her growth.But,when he or ...

  10. node包管理相关

    切换npm数据源 镜像使用方法(三种办法任意一种都能解决问题,建议使用第三种,将配置写死,下次用的时候配置还在): 1.通过config命令 npm config set registry https ...