标签:oca 公交车 剩余定理 题目 style stop sizeof tar typedef
A-Evolution Game
题目大意:有$n$个不同的野兽,定义第$i$ 个野兽有 $i$ 个眼睛和 $h[i]$ 个角,你可以任意从中选择一个野兽进行进化,每次进化角数量必须增加,而且进化后要满足眼镜的变化量 $\triangle i \leq w$,求最多的进化次数。
题解:以$h$的值从大到小排序,$f[i]$表示从第i个野兽开始进化的最多次数。对于$1 \leq i \leq j$若满足条件则$f[j]=max \{ f[i]+1 \}$。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cmath> 5 #include<cstring> 6 #include<algorithm> 7 using namespace std; 8 9 int n,w,ans; 10 int f[5005]; 11 struct hh 12 { 13 int eye,horn; 14 }a[5005]; 15 bool cmp(hh a,hh b) 16 { 17 return a.horn>b.horn; 18 } 19 int main() 20 { 21 int i,j;; 22 scanf("%d%d",&n,&w); 23 for(i=1;i<=n;i++) 24 scanf("%d",&a[i].horn); 25 for(i=1;i<=n;i++) 26 a[i].eye=i; 27 sort(a+1,a+1+n,cmp); 28 for(i=1;i<=n;i++) 29 for(j=i+1;j<=n;j++)//h[i]>h[j] 30 if(a[i].horn>a[j].horn&&abs(a[i].eye-a[j].eye)<=w) 31 f[j]=max(f[j],f[i]+1); 32 for(i=1;i<=n;i++) 33 ans=max(f[i],ans); 34 printf("%d",ans); 35 return 0; 36 }
D-Bus Stop
题目大意:给出$n$个房子的坐标,要建立公交车站使得每个房子离最近的车站不过10公里,求最少的车站数。
题解:从左往右贪心即可。
#include <bits/stdc++.h> using namespace std; const int N=3e6; int m,n; int a[N]; int ans,lstop; int main() { scanf("%d",&m); while(m--) { scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } lstop=a[1]+10; ans=1; for(int i=2;i<=n;i++){ if(abs(a[i]-lstop)<=10){ ; } else{ lstop=a[i]+10; ans++; } } if(n==0)ans=0; if(n==1)ans=1; printf("%d\n",ans); } }
G-Communication
题目大意:求有向图强连通分量数。
题解:Floyed+并查集或者Tarjan。
#include <bits/stdc++.h> using namespace std; const int N=1e3; int m,n,c,ans,a,b; int f[N]; int edge[N][N]; int fnd(int x) { if(f[x]==x)return x; return f[x]=fnd(f[x]); } int main() { scanf("%d",&m); while(m--) { scanf("%d%d",&n,&c); memset(edge,0,sizeof(edge)); for(int i=0;i<n;i++) f[i]=i; for(int i=1;i<=c;i++){ scanf("%d%d",&a,&b); edge[a][b]=1; } for(int k=0;k<n;k++) for(int i=0;i<n;i++) for(int j=0;j<n;j++){ if(edge[i][k]&&edge[k][j])edge[i][j]=1; } ans=0; for(int i=0;i<n-1;i++) for(int j=i+1;j<n;j++){ if(edge[i][j]+edge[j][i]==2){ f[j]=fnd(i); } } for(int i=0;i<n;i++){ if(f[i]==i)ans++; } printf("%d\n",ans); } }
H-As rich as Crassus
题目大意:$x^3 \equiv A_i \ \ (mod \ \ N_i) (i=3)$,求$x$。
题解:中国剩余定理
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> using namespace std; int n,t; long long ans; long long b[15],m[15]; long long exgcd(long long a,long long b,long long &x,long long &y){ if(b==0){x=1,y=0;return a;} long long d=exgcd(b,a%b,x,y); long long z=x;x=y,y=z-a/b*y; return d; } void print(long long x){ if(!x) return; if(x) print(x/10); putchar(x%10+‘0‘); } int main() { int i; long long x,y,M,aa,bb,cc,d,tmp; bool flag;n=3; scanf("%d",&t); while(t--) { ans=flag=0; for(i=1;i<=n;i++) scanf("%I64d",&m[i]); for(i=1;i<=n;i++) scanf("%I64d",&b[i]); M=m[1],ans=b[1]; for(i=2;i<=n;i++) { aa=M,bb=m[i],cc=(b[i]-ans%bb+bb)%bb; x=0,y=0; d=exgcd(aa,bb,x,y); bb=bb/d; if(cc%d){flag=1;break;} x=((x*cc/d)%bb+bb)%bb; ans+=M*x;M*=bb; ans=(ans%M+M)%M; } if(flag)puts("-1"); else { if(!ans)puts("0"); else { tmp=pow(ans,1.0/3.0); if(tmp*tmp*tmp<ans) printf("%I64d\n",tmp+1); else printf("%I64d",tmp); } } } return 0; } close
J-Floating-Point Hazard
题目大意:给出L,R,求$\sum_{i=L}^{R}(\sqrt[3]{i+10^{-15}}-\sqrt[3]{i})$。
题解:微分
#include <iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> using namespace std; typedef long long ll; int main() { #ifdef LOCAL freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); #endif // LOCAL int a,b; while(~scanf("%d%d",&a,&b)){ if(!a||!b) break; double ans=0; for(ll i=a;i<=b;i++){ ans+=pow(i*i,-1/3.0); } ans*=1.0/3*(1e-15); printf("%.5E\n",ans); } }
K-The Stream of Corning 2
题目大意:给出若干个数和存在的时间点,问某一时刻存在的数中的第k大。
题解:将一个操作的起始点和终止点拆开标记,按时间排序后,用树状数组+二分求动态第k大数。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> using namespace std; int t,n,totp,totq,lim; struct hh { int opt,t,v,k,id; }p[200005],q[200005]; int c[20000005]; int lowbit(int x) { return x&(-x); } void add(int pos,int v) { for(;pos<=lim;pos+=lowbit(pos)) c[pos]+=v; } int query(int pos) { int ret=0; for(;pos;pos-=lowbit(pos)) ret+=c[pos]; return ret; } bool cmp(hh a,hh b) { return a.t<b.t; } bool cmp2(hh a,hh b) { return a.id<b.id; } int solve(int k) { int l,r,mid,ret,n; l=1;r=lim; ret=lim; if(query(lim)<k) return -1; while(l<=r) { mid=l+r>>1; if(query(mid)>=k) { r=mid-1; ret=min(ret,mid); } else l=mid+1; } return ret; } int main() { int T,i,j,a,b,z,prep,opt; scanf("%d",&t); for(T=1;T<=t;T++) { scanf("%d",&n); totp=totq=0; memset(p,0,sizeof(p)); memset(q,0,sizeof(q)); memset(c,0,sizeof(c)); for(i=1;i<=n;i++) { scanf("%d%d%d",&opt,&a,&b); lim=max(lim,b); if(opt==1) { scanf("%d",&z); p[++totp].opt=1; p[totp].v=b; p[totp].t=a; p[++totp].opt=-1; p[totp].v=b; p[totp].t=z; } else { q[++totq].t=a; q[totq].k=b; q[totq].id=i; } } sort(p+1,p+1+totp,cmp); sort(q+1,q+1+totq,cmp); prep=1; for(i=1;i<=totq;i++) { while(p[prep].t<q[i].t&&prep<=totp) { add(p[prep].v,p[prep].opt); prep++; } q[i].v=solve(q[i].k); } sort(q+1,q+1+totq,cmp2); printf("Case %d:\n",T); for(i=1;i<=totq;i++) printf("%d\n",q[i].v); } return 0; }
L-Largest Allowed Area
题目大意:求一个最大的子矩阵,要求子矩阵的和为0或1。
题解:单调队列。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<cmath> #include<algorithm> using namespace std; int t,n,m,ans; int s[1005][1005],a[1005][1005]; char c; int main() { int i,j; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); memset(s,0,sizeof(s)); memset(a,0,sizeof(a)); for(i=1;i<=n;i++) for(j=1;j<=m;j++) { do{c=getchar();}while(c!=‘0‘&&c!=‘1‘); s[i][j]=c-‘0‘+s[i-1][j]+s[i][j-1]-s[i-1][j-1]; } for(i=1,ans=1;i<=n;i++) for(j=1;j<=m;j++) { a[i][j]=a[i-1][j-1]-(a[i-1][j-1]>=1); while(i+a[i][j]<=n&&j+a[i][j]<=m&&s[i+a[i][j]][j+a[i][j]]-s[i-1][j+a[i][j]]-s[i+a[i][j]][j-1]+s[i-1][j-1]<=1) a[i][j]++; ans=max(ans,a[i][j]); } printf("%d\n",ans); } return 0; }
【GYM102091】2018-2019 ACM-ICPC, Asia Nakhon Pathom Regional Contest
标签:oca 公交车 剩余定理 题目 style stop sizeof tar typedef
原文地址:https://www.cnblogs.com/yljiang/p/10545991.html