*感谢两位浙江大佬带我飞
贴下成绩
div2
div1
*div2不是我打的上个厕所就5/11了
比赛小结
A
【题目大意】
有n(n<=500)个机场,两两之间距离是g[i][j],每经停一个机场需要p[i]的时间维修
有m条线路,描述为出发机场,终点机场,出发时间,求航空公司至少需要多少架飞机
每条航线必须直飞
但是转机的时候可以劲停多个机场
【题解】
首先一架飞机能在完成航线A后去飞航线B的条件很显然。就是
表示两点间最短路。那么我们可以用这个不等式把问题转化为最小路径覆盖问题
我想了下这个最短路用Floyd吧n^3我选择死亡时限是5s应该能过的
然后忧虑了一下我的dinic的常数,写了个匈牙利,但是之后有人和我讲dinic更快?
#include<map> #include<stack> #include<queue> #include<cstdio> #include<string> #include<vector> #include<cstring> #include<complex> #include<iostream> #include<assert.h> #include<algorithm> using namespace std; #define inf 1001001001 #define infll 1001001001001001001LL #define FOR0(i,n) for(int (i)=0;(i)<(n);++(i)) #define ll long long #define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl #define gmax(a,b) (a)=max((a),(b)) #define gmin(a,b) (a)=min((a),(b)) #define ios0 ios_base::sync_with_stdio(0) #define Ri register int #define gc getchar() #define il inline #define FOR1(i,n) for(Ri (i)=1;(i)<=(n);++(i)) il int read(){ bool f=true; Ri x=0;char ch; while(!isdigit(ch=gc))if(ch=='-')f=false; while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=gc;} return f?x:-x; } #define gi read() int n,m,p[555],g[555][555],f[555][555]; struct edge{ int to,next; }e[555*555],s1[555],s2[555]; int cnt,last[666],match[666],vis[666]; void insert(int a,int b){ e[++cnt]=(edge){b,last[a]};last[a]=cnt; } int hungary(int u){ vis[u]=1; for(int i=last[u];i;i=e[i].next){ int y=e[i].to; if(match[y]==-1){ match[y]=u; return 1; } } for(int i=last[u];i;i=e[i].next){ int y=e[i].to; if(!vis[match[y]]&&hungary(match[y])){ match[y]=u; return 1; } } return 0; } int main(){ n=gi;m=gi; FOR1(i,n)p[i]=gi; FOR1(i,n)FOR1(j,n){ int T=gi; if(i^j)g[i][j]=T+p[j]; else g[i][j]=T; f[i][j]=g[i][j]; } //n^3 floyd FOR1(k,n)FOR1(i,n)FOR1(j,n)gmin(f[i][j],f[i][k]+f[k][j]); FOR1(i,m){ int a,b,c; a=gi;b=gi;c=gi; s1[i]=(edge){a,c}; s2[i]=(edge){b,c+g[a][b]}; } FOR1(i,m){ match[i]=-1; FOR1(j,m)if(i^j){ if(s2[i].next+f[s2[i].to][s1[j].to]<=s1[j].next)insert(i,j); } } int fyb=n; FOR1(i,m){ memset(vis,0,sizeof(vis)); if(hungary(i))--fyb; } printf("%d",fyb); return 0; }
C
【题目大意】
有n个人,他们的评级是由上(upper)中(middle)下(lower)组成的
两个评级的高底是从最后一个开始比较到第一个,一个中文的世纪大难题
求出从高到低的排列顺序
【题解】分类并排序md这都什么鬼题目啊
#include<map> #include<stack> #include<queue> #include<cstdio> #include<string.h> #include<vector> #include<cstring> #include<complex> #include<iostream> #include<assert.h> #include<algorithm> using namespace std; #define inf 1001001001 #define infll 1001001001001001001LL #define FOR0(i,n) for(int (i)=0;(i)<(n);++(i)) #define FOR1(i,n) for(int (i)=1;(i)<=(n);++(i)) #define ll long long #define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl #define gmax(a,b) (a)=max((a),(b)) #define gmin(a,b) (a)=min((a),(b)) #define ios0 ios_base::sync_with_stdio(0) #define Ri register int #define gc getchar() #define il inline il int read(){ bool f=true; Ri x=0;char ch; while(!isdigit(ch=gc))if(ch=='-')f=false; while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=gc;} return f?x:-x; } #define gi read() #define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout); int n; struct data{ char name[299]; int b[50]; bool operator<(data B)const{ for(int i=1;i<=49;i++) if(b[i]!=B.b[i]) return b[i]>B.b[i]; return strcmp(name,B.name)<0; } }a[1010]; int main(){ n=gi; FOR1(i,n){ scanf("%s",a[i].name);a[i].name[strlen(a[i].name)-1]='\0'; int p=0,temp[33]; char str[33]; while(scanf("%s",str),str[0]!='c'){ if(str[0]=='u')temp[++p]=1; if(str[0]=='m')temp[++p]=0; if(str[0]=='l')temp[++p]=-1; } int fyb=0; while(p)a[i].b[++fyb]=temp[p--]; } sort(a+1,a+n+1); FOR1(i,n)printf("%s\n",a[i].name); }
D
【题目大意】给定俩三角形问能不能拼成一个矩形
【题解】这你告诉我不会做回去种田吧
E
【题目大意】给定一个长度为偶数的能力值序列,要求两两分组,使得每组能力值的和的最小值最大
【题解】排序后贪心
G
【题目大意】给你一个w*h的矩形,w,h<=10^9。我们一开始在y=0的任一位置。开始移动当纵向速度是v,那么横向速度是[-v/r,v/r]之间,r是给定的小于等于10的正整数,给定10^5个点,问最多能抵达多少个点
【题解】
意给的是你移动的角度,考虑怎么转化这个东西
首先可以推算出来,
旋转这个坐标轴是最好的做法
我们把整个平面上的所有图形绕原点顺时针旋转某个度数。
举个例子,当r=1时,原来是的坐标就变成为方便计算把它乘得到
由于角度在之间的都是合法的
那么我们就把坐标轴旋转,这么做的目的是使得移动的影响同时反映在上,而且可以计算
那么我们旋转这个度数之后,原有的,就变成了
所以我们只要对双关键字排序,第二维的LIS长度就是答案
言语有点混乱
如果哪里写错了请不要告诉我
#include<map> #include<stack> #include<queue> #include<cstdio> #include<string> #include<vector> #include<cstring> #include<complex> #include<iostream> #include<assert.h> #include<algorithm> using namespace std; #define inf 1001001001 #define infll 1001001001001001001ll #define FOR0(i,n) for(int (i)=0;(i)<(n);++(i)) #define FOR1(i,n) for(int (i)=1;(i)<=(n);++(i)) #define ll long long #define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl #define gmax(a,b) (a)=max((a),(b)) #define gmin(a,b) (a)=min((a),(b)) #define ios0 ios_base::sync_with_stdio(0) #define Ri register int #define gc getchar() #define il inline il int read(){ bool f=true; Ri x=0;char ch; while(!isdigit(ch=gc))if(ch=='-')f=false; while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=gc;} return f?x:-x; } il ll read2(){ bool f=true; ll x=0;char ch; while(!isdigit(ch=gc))if(ch=='-')f=false; while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=gc;} return f?x:-x; } #define gi read() #define gl read2() #define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout); const int N=100005; struct data{ll x,c;}a[N]; int n,r,w,h; ll x,y; ll d[N]; bool cmp(const data&a,const data&b){ return a.c<b.c; } int main(){ n=gi;r=gi;w=gi;h=gi; FOR1(i,n){ ll x,y; x=gl;y=gl; a[i].c=r*x+y; a[i].x=-r*x+y; } sort(a+1,a+n+1,cmp); d[0]=-infll; int len=0; FOR1(i,n){ if(a[i].x>=d[len])d[++len]=a[i].x; else d[lower_bound(d+1,d+len+1,a[i].x)-d]=a[i].x; } printf("%d\n",len); return 0; }
比赛&题面链接
http://codeforces.com/gym/100820