noip2011提高组day1+day2解题报告
Day1 T1铺地毯https://www.luogu.org/problem/show?pid=1003
【题目分析】
全部读入以后从最后一个往前找,找到一个矩形的范围覆盖了这个点,那这个矩形就是最上面的地毯,输出即可
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=10010; int a[maxn],b[maxn],g[maxn],k[maxn]; int n,ans=-1; int x,y; int main() { freopen("carpet.in","r",stdin); freopen("carpet.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d%d%d",&a[i],&b[i],&g[i],&k[i]); scanf("%d%d",&x,&y); int xx=n; while(xx--) { if((a[xx+1]<=x)&&(a[xx+1]+g[xx+1]>=x)&&(b[xx+1]<=y)&&(b[xx+1]+k[xx+1]>=y)) { ans=xx+1; break; } } printf("%d",ans); }
Day1 T2选择客栈https://www.luogu.org/problem/show?pid=1311
【题目分析】
首先说一下O(nk)的做法。zzl[i]表示第i种颜色的数量,bfh[i]表示不符合条件的酒店的数量,sum表示不符合条件的方案数,ans表示相同色调的酒店组合的所有情况
#include<cstdio> #include<cstring> #include<iostream> using namespace std; int n,k,p; const int maxn=200010; int a[maxn],b[maxn],zzl[55],bfh[55]; int ans=0,sum=0; int main() { freopen("hotel.in","r",stdin); freopen("hotel.out","w",stdout); scanf("%d%d%d",&n,&k,&p); for(int i=1;i<=n;i++) { scanf("%d%d",&a[i],&b[i]); if(b[i]<=p) { for(int j=0;j<k;j++) { sum+=bfh[j]*(bfh[j]-1)/2; bfh[j]=0; } zzl[a[i]]++; } else bfh[a[i]]++, zzl[a[i]]++; } for(int i=0;i<k;i++) ans+=zzl[i]*(zzl[i]-1)/2, sum+=bfh[i]*(bfh[i]-1)/2; printf("%d",ans-sum); return 0; }
//当复杂度变为O(n)...我也不太会,codevs上的题解不错 #include<iostream> using namespace std; int n,k,p,m,x,y,sum; int a[100],b[100],c[100]; int main() { cin>>n>>k>>p; for(int i=1;i<=n;i++) { cin>>x>>y; if(y<=p) m=i;//如果咖啡店的最低消费地于标准,那么记录其位置 if(m>=a[x]) c[x]=b[x];//如果在当前颜色的酒店之前有出现过同样颜色的酒店那么记录当前同种颜色的酒店的出现次数 /*特注:当到COODVS上第四组数据时也许会因为“y<=p”不会记录当前的位置, 但是会记录之前有满足“y<=p”条件的位置, 也就是说两个人住的客栈之间有满足条件的咖啡馆, 那么也就可以让c数组的对应颜色加上1了,即“c[x]=b[x]” 从而使后面的总数加上1*/ a[x]=i;//记录同样颜色的酒店最后一次的出现位置 sum+=c[x]; /*每一个酒店都可以作为对应点,所以不需要再去加上任何的判断,记录住宿的方法, c数组可以理解为当前色调位置,到之前满足“y<=p”色调位置的方案 */ b[x]++;//记录出现次数的总数 } cout<<sum; return 0; }
版权声明:本文为xiaoningmeng原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。