USACO2014Open Fair Photography
来源:互联网 发布:ubuntu如何安装wine 编辑:程序博客网 时间:2024/05/19 07:41
Fair Photography
FJ’s N cows (1 <= N <= 100,000) are standing at various positions along a long one-dimensional fence. The ith cow is standing at position x_i (an integer in the range 0…1,000,000,000) and has breed b_i (an integer in the range 1..8). No two cows occupy the same position.
FJ wants to take a photo of a contiguous interval of cows for the county fair, but we wants all of his breeds to be fairly represented in the photo. Therefore, he wants to ensure that, for whatever breeds are present in the photo, there is an equal number of each breed (for example, a photo with
27 each of breeds 1 and 3 is ok, a photo with 27 of breeds 1, 3, and 4 is ok, but 9 of breed 1 and 10 of breed 3 is not ok). Farmer John also wants at least K (K >= 2) breeds (out of the 8 total) to be represented in the photo. Help FJ take his fair photo by finding the maximum size of a photo that satisfies FJ’s constraints. The size of a photo is the difference between the maximum and minimum positions of the cows in the photo.
If there are no photos satisfying FJ’s constraints, output -1 instead.PROBLEM NAME: fairphoto
INPUT FORMAT:
Line 1: N and K separated by a space
Lines 2..N+1: Each line contains a description of a cow as two integers separated by a space; x(i) and its breed id.SAMPLE INPUT (file fairphoto.in):
9 2
1 1
5 1
6 1
9 1
100 1
2 2
7 2
3 3
8 3INPUT DETAILS:
Breed ids: 1 2 3 - 1 1 2 3 1 - … - 1
Locations: 1 2 3 4 5 6 7 8 9 10 … 99 100OUTPUT FORMAT:
Line 1: A single integer indicating the maximum size of a fair photo. If no such photo exists, output -1.
SAMPLE OUTPUT (file fairphoto.out):
6
OUTPUT DETAILS:
The range from x = 2 to x = 8 has 2 each of breeds 1, 2, and 3. The range from x = 9 to x = 100 has 2 of breed 1, but this is invalid because K = 2 and so we must have at least 2 distinct breeds.
Task:
给定一行
Solution:
首先考虑
#include<stdio.h>#include<iostream>#include<algorithm>#define M 100005using namespace std;struct Node{ int x,c; bool operator <(const Node &a)const{ return x<a.x; }}A[M];int sum[10][M];int main(){ int n,k,ans=-1; scanf("%d %d",&n,&k); for(int i=1;i<=n;i++) scanf("%d %d",&A[i].x,&A[i].c); sort(A+1,A+n+1); for(int i=1;i<=n;i++) for(int j=1;j<=8;j++) if(j==A[i].c)sum[j][i]=sum[j][i-1]+1; else sum[j][i]=sum[j][i-1]; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++){ if(A[j].x-A[i].x<=ans)continue; int cnt=0,sm=-1; for(int t=1;t<=8;t++){ if(sum[t][j]-sum[t][i-1]==0)continue; if(sm==-1)sm=sum[t][j]-sum[t][i-1]; if(sm!=sum[t][j]-sum[t][i-1]){ cnt=-1; break; }else cnt++; } if(cnt>=k){ if(A[j].x-A[i].x>ans)ans=A[j].x-A[i].x; } } printf("%d\n",ans); return 0;}
然后,我们就要考虑如何枚举右端点,直接算出左端点的位置。我们发现,对于左右两个满足条件的端点处的前缀,各种种类的牛的差值是一样的。计
- A是一些种类组成的集合
S(A,p) 包括每一个在A 中的种类与第一个在A 中的种类在区间[1,p] 中的个数之差
我们现在只需要对于一个
标程的做法好像是
#include<stdio.h>#include<iostream>#include<algorithm>#define M 100005#define P 99937#define ll unsigned long longusing namespace std;struct Node1{ int x,c; bool operator <(const Node1 &a)const{ return x<a.x; }}A[M];int n,k,ans=-1,mx=0;bool mark[8];int Q[M],top=0;struct HASH{ int cnt; int nxt[M],last[M],val[M]; ll Hash[M]; void insert(ll H,int t){ int x=H%P; Q[++top]=x; cnt++; nxt[cnt]=last[x];val[cnt]=t;Hash[cnt]=H; last[x]=cnt; } int find(ll H){ int x=H%P; for(int i=last[x];i;i=nxt[i]) if(Hash[i]==H)return val[i]; return -1; } void clear(){ while(top)last[Q[top--]]=0; cnt=0; }}mp;void Rd(int &res){ res=0; char c; while(c=getchar(),!isdigit(c)); do{ res=(res<<1)+(res<<3)+c^48; }while(c=getchar(),isdigit(c));}ll GetHash(int cnt[]){ ll res=0; for(int i=0;i<mx;i++) res=res*1000000009+cnt[i]*233; return res;}void check(){ int cnt[8]={0}; int p=0; while(!mark[p])p++; mp.clear(); mp.insert(0,1); for(int R=1;R<=n;R++){ if(!mark[A[R].c]){ mp.clear(); for(int i=0;i<mx;i++)cnt[i]=0; mp.insert(0,R+1); }else{ if(A[R].c==p){ for(int j=p+1;j<mx;j++) if(mark[j])cnt[j]--; }else cnt[A[R].c]++; ll h=GetHash(cnt); int t=mp.find(h); if(t==-1)mp.insert(h,R+1); else{ if(A[R].x-A[t].x>ans)ans=A[R].x-A[t].x; } } }}void dfs(int x,int cnt){ if(x==mx){ if(cnt>=k)check(); return; } mark[x]=true; dfs(x+1,cnt+1); mark[x]=false; dfs(x+1,cnt);}int main(){ scanf("%d %d",&n,&k); for(int i=1;i<=n;i++){ scanf("%d %d",&A[i].x,&A[i].c); if(A[i].c>mx)mx=A[i].c; A[i].c--; } sort(A+1,A+n+1); dfs(0,0); printf("%d\n",ans); return 0;}
- USACO2014Open Fair Photography
- USACO2014Open Silver Fair Photography
- USACO2014Open Gold Fair Photography
- bzoj3540【Usaco2014 Open】Fair Photography
- 3540: [Usaco2014 Open]Fair Photography
- bzoj 3535Fair Photography【hash】
- 3540: [Usaco2014 Open]Fair Photography
- [USACO 2014 Mar Silver]Fair Photography
- bzoj 3540: [Usaco2014 Open]Fair Photography
- USACO2014Open Odometer
- Photography tip.
- GEORGIEW photography
- Photography Summary
- Photography Masterclass
- USACO2014Open Gold optics
- USACO2014Open Silver Dueling GPSs
- USACO2014Open Silver Odometer
- USACO2014Open Gold Cow Optics
- Jvm内存管理
- iOS学习之 plist文件的读写
- 查询网址主机托管信息
- Linux-Shell脚本编程-学习-5-Shell编程-使用结构化命令-if-then-else-elif
- 移动应用开发
- USACO2014Open Fair Photography
- sql语句union用法,根据字段顺序进行合并,而不是字段名称
- Android 7.0新特性---删除三项广播
- IIS 部署ASP.Net, WebAPI, Restful API, PUT/DELETE 报405错解决办法, webapi method not allowed 405
- mgo 聚类统计
- JS写一个LED显示屏
- linux上获取shell脚本所在目录
- day15 python随机生成验证码的代码
- 360图书馆 解除网页防复制