Codeforces #283 Div 1 简要题解
来源:互联网 发布:写给自己的情书 知乎 编辑:程序博客网 时间:2024/05/12 10:53
比赛总结
算了不提了,比赛时只弄出来第一题,wa了7次,罚时跪得一塌糊涂,*了狗了。。。
A. Removing Columns
题目链接
http://codeforces.com/contest/497/problem/A
题目大意
给你
思路
非常坑爹的细节题,其间不知道wa了多少次。。。。
显然是个贪心,我们从第一列到最后一列扫,只要能保留的列,保留下来肯定对后面没有影响。
如果当前在保留下来的列中,某些字符串的前缀都一样:
AAAAAA?…..
AAAAAA?…..
…….
AAAAAA?…..
那么?列就必须得按照字母非降排序,类似下面这样
AAAAAA A…..
AAAAAA B…..
…….
AAAAAA E…..
否则这一列随便什么顺序都行
我们可以维护一个数组
代码
#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <algorithm>#define MAXN 510using namespace std;char mp[MAXN][MAXN];int n,m,maxans=0;bool mark[MAXN];int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%s",mp[i]+1); int ans=0; for(int j=1;j<=m;j++) { bool flag=true; for(int i=1;i<n;i++) { if(!mark[i]&&mp[i][j]>mp[i+1][j]) { ans++; flag=false; break; } } if(flag) { for(int i=1;i<n;i++) if(mp[i][j]<mp[i+1][j]) mark[i]=true; } } printf("%d\n",ans); return 0;}
B. Tennis Game
题目链接
http://codeforces.com/contest/497/problem/B
题目大意
A和B打
思路
首先我们枚举
代码
#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <algorithm>#include <vector>#define MAXN 210000using namespace std;int n;int result[MAXN];int sumA[MAXN],sumB[MAXN];vector<pair<int,int> >sol;int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&result[i]); for(int i=1;i<=n;i++) { sumA[i]=sumA[i-1]+(result[i]==1); sumB[i]=sumB[i-1]+(result[i]==2); } for(int t=1;t<=n;t++) { int totA=0,totB=0,p=0; while(p<n) { int lowerBound=p+1,upperBound=n,ans=-1; while(lowerBound<=upperBound) { int mid=(lowerBound+upperBound)>>1; if(sumA[mid]-sumA[p]>=t||sumB[mid]-sumB[p]>=t) { ans=mid; upperBound=mid-1; } else lowerBound=mid+1; } if(ans==-1) break; if(sumA[ans]-sumA[p]>=t&&sumB[ans]-sumB[p]<t) totA++; if(sumA[ans]-sumA[p]<t&&sumB[ans]-sumB[p]>=t) totB++; if(ans==n&&totA!=totB) { if(totA>totB&&result[ans]!=1) break; if(totA<totB&&result[ans]!=2) break; sol.push_back(make_pair(max(totA,totB),t)); } p=ans; } } sort(sol.begin(),sol.end()); printf("%d\n",sol.size()); for(int i=0;i<sol.size();i++) printf("%d %d\n",sol[i].first,sol[i].second); return 0;}
C. Distributing Parts
题目链接
http://codeforces.com/contest/497/problem/C
题目大意
给你
思路
比较简单的贪心。我们首先将红色线段和蓝色线段按照第一关键字右端点升序、第二关键字左端点升序来排序,然后从左到右扫蓝色线段
代码
#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <algorithm>#include <vector>#include <set>#define MAXN 210000using namespace std;int n,m;struct Segment{ int L,R,k,id;}song[MAXN],musician[MAXN];bool operator<(Segment a,Segment b){ if(a.R==b.R) return a.L<b.L; return a.R<b.R;}int belong[MAXN];struct Info{ int L,R,id; Info(){} Info(int _L,int _R,int _id):L(_L),R(_R),id(_id){}};bool operator<(Info a,Info b){ if(a.L==b.L) return a.R<b.R; return a.L<b.L;}bool operator>(Info a,Info b){ if(a.L==b.L) return a.R>b.R; return a.L>b.L;}multiset<Info>bst; //!!!multiset<Info>::iterator it;int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&song[i].L,&song[i].R); song[i].id=i; } scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d%d%d",&musician[i].L,&musician[i].R,&musician[i].k); musician[i].id=i; } sort(song+1,song+n+1); sort(musician+1,musician+m+1); int p=1,tot=0; //tot=被演奏的歌曲个数 for(int i=1;i<=m;i++) { for(;p<=n&&song[p].R<=musician[i].R;p++) { //cout<<"L:"<<song[p].L<<" R:"<<song[p].R<<endl; bst.insert(Info(song[p].L,song[p].R,song[p].id)); } for(int t=1;t<=musician[i].k;t++) { it=bst.lower_bound(Info(musician[i].L,0,0)); if(it==bst.end()) break; belong[it->id]=musician[i].id; bst.erase(it); tot++; } } if(tot!=n) { printf("NO\n"); return 0; } printf("YES\n"); for(int i=1;i<=n;i++) printf("%d ",belong[i]); printf("\n"); return 0;}
D. Gears
题目链接
http://codeforces.com/contest/497/problem/D
题目大意
给你两个多边形,每个多边形会以一个点为中心顺时针旋转。两个多边形旋转的速度(rad/s)相同,每个多边形各有一个旋转中心。
问这两个多边形旋转过程中是否会发生碰撞
思路
观察发现,碰撞发生时,肯定是一个多边形的顶点撞上了另一个多边形的边。不妨设多边形B的顶点撞上了多边形A的边(多边形A的顶点撞上了多边形B的边的情况,只需要把A和B对换一下就行了)。我们不妨固定多边形A不动,让B绕着A做逆时针公转,自己做顺时针自转,公转和自转的速率相同。
如上图,设多边形A的旋转中心为P,B的中心为Q。则B公转的轨道就是图上蓝色的、以P为圆心、半径为PQ的圆。设黄色点
代码
#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <algorithm>#define MAXN 1100using namespace std;typedef long long int LL;struct Point{ LL x,y; Point(){} Point(LL _x,LL _y):x(_x),y(_y){}}pA[MAXN],pB[MAXN],centerA,centerB;int n,m;Point operator-(Point a,Point b){ return Point(a.x-b.x,a.y-b.y);}Point operator+(Point a,Point b){ return Point(a.x+b.x,a.y+b.y);}LL cross(Point a,Point b){ return a.x*b.y-a.y*b.x;}LL dist(Point a,Point b){ return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}struct Line{ Point st,ed; Line(){} Line(Point _st,Point _ed):st(_st),ed(_ed){}};bool check() //为了防止被坑爹卡精度,所有的距离全部是实际距离的平方,面积也得是平方{ LL R=dist(centerA,centerB); //公转轨道的圆的半径 for(int i=1;i<=m;i++) //枚举B上的点i落到了A上面 { Point tmpC=centerA+(pB[i]-centerB); for(int j=1;j<=n;j++) //枚举A上的边j->j+1 { Point tmpA=pA[j],tmpB=pA[j%n+1]; LL disA=dist(tmpA,tmpC),disB=dist(tmpB,tmpC); if(disA-R<=0&&disB-R>=0) //disA和disB中一个比R大,一个比R小,表明A上的边j->j+1会碰撞上B上的点i return true; if(disA-R>=0&&disB-R<=0) //disA和disB中一个比R大,一个比R小,表明A上的边j->j+1会碰撞上B上的点i return true; //if(disA-R<0&&disB-R<0) continue; if(max(disA,disB)*2>disA+disB+dist(tmpA,tmpB)) continue; if(cross(tmpC-tmpA,tmpB-tmpA)*cross(tmpC-tmpA,tmpB-tmpA)<=R*dist(tmpA,tmpB)&&disA>=R) //!!!!B上的点i到边j->j+1的距离小于等于R return true; } } return false;}int main(){ scanf("%I64d%I64d",¢erA.x,¢erA.y); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%I64d%I64d",&pA[i].x,&pA[i].y); scanf("%I64d%I64d",¢erB.x,¢erB.y); scanf("%d",&m); for(int i=1;i<=m;i++) scanf("%I64d%I64d",&pB[i].x,&pB[i].y); if(check()) { printf("YES\n"); return 0; } swap(n,m); swap(centerA,centerB); swap(pA,pB); if(check()) { printf("YES\n"); return 0; } printf("NO\n"); return 0;}
- Codeforces #283 Div 1 简要题解
- [Codeforces #295(Div 1)]简要题解
- Codeforces #299 Div 1 简要题解
- Codeforces #292 Div 1 简要题解
- Codeforces #305 Div 1 简要题解
- Codeforces #290 Div. 1 简要题解
- Codeforces #286 Div 1 简要题解
- Codeforces #285 Div 1 简要题解
- Codeforces #284 Div 1 简要题解
- Codeforces #278 Div 1 简要题解
- Codeforces #275 Div 1 简要题解
- Codeforces #274 Div 1 简要题解
- Codeforces #272 Div 1 简要题解
- Codeforces #268 Div 1 简要题解
- Codeforces #265 Div 1 简要题解
- Codeforces #263 Div 1 简要题解
- Codeforces #310 Div 1 简要题解
- Codeforces #309 Div 1 简要题解
- 将c语言注释转换成c++注释
- 字符串 单词数
- linux下实现event
- LightOJ1408(数学期望与概率)
- maven失败测试用例rerun插件使用方法
- Codeforces #283 Div 1 简要题解
- Opencv 报错:vector subscript out of range
- 原材料批次管理立体仓库库位管理生产领料管理生产线工序管理产成品系列号唯一码管理产品质量追溯管理
- C++解析和初始化
- 利用GDI+基于WIN32实现桌面雪花效果(一)
- C语言基础:进制转换,变量,常量,表达式,基本数据类型,输出函数,输入函数,运算符.
- 2015061002 - 茂陵
- 组合数
- ViewPager+FragmentPagerAdapter+RadioGroup实现顶部菜单栏(一)