Codeforces Round#509 Div.2翻車記
阿新 • • 發佈:2018-09-17
n) 長度 cin namespace ORC ces algorithm 一次 isp
A:簽到
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<‘0‘||c>‘9‘) {if (c==‘-‘) f=-1;c=getchar();} while (c>=‘View Code0‘&&c<=‘9‘) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 1010 int n,a[N]; int main() { n=read(); for (int i=1;i<=n;i++) a[i]=read(); sort(a+1,a+n+1); cout<<a[n]-a[1]+1-n; return 0; }
B:簽到
#include<iostream> #includeView Code<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<‘0‘||c>‘9‘) {if (c==‘-‘) f=-1;c=getchar();} while (c>=‘0‘&&c<=‘9‘) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define ll long long ll a,b,x,y; ll gcd(ll n,ll m){return m==0?n:gcd(m,n%m);} int main() { cin>>a>>b>>x>>y; ll tmp=gcd(x,y);x/=tmp,y/=tmp; cout<<min(a/x,b/y); return 0; }
C:貪心,每次選擇最後一次喝咖啡最早的一天,看是否能將此次喝咖啡加入這天,不行就新開一天。堆維護即可。開始的時候寫了半天線性的一直wa on 9,掉rating瞬間穩了。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> #include<queue> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<‘0‘||c>‘9‘) {if (c==‘-‘) f=-1;c=getchar();} while (c>=‘0‘&&c<=‘9‘) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 200010 int n,m,k,tot,ans[N]; struct data{int x,i; bool operator <(const data&a) const { return x<a.x; } }a[N]; struct data2{int id,tim; bool operator <(const data2&a) const { return tim>a.tim; } }; priority_queue<data2> q; int main() { n=read(),m=read(),k=read()+1; for (int i=1;i<=n;i++) a[i].x=read(),a[i].i=i; sort(a+1,a+n+1); for (int i=1;i<=n;i++) { if (q.empty()||q.top().tim+k>a[i].x) { tot++;ans[a[i].i]=tot; q.push((data2){tot,a[i].x}); } else { ans[a[i].i]=q.top().id; data2 y=q.top();q.pop(); q.push((data2){y.id,a[i].x}); } } cout<<tot<<endl; for (int i=1;i<=n;i++) printf("%d ",ans[i]); return 0; }View Code
D:按間隔長度尺取即可。沒看到沒有相交段,慘慘。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<‘0‘||c>‘9‘) {if (c==‘-‘) f=-1;c=getchar();} while (c>=‘0‘&&c<=‘9‘) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 200010 int n,m,cnt,c[N],d[N],ans,t=0; struct data{int x,y; bool operator <(const data&a) const { return x<a.x; } }a[N],b[N]; int main() { n=read(),m=read(); for (int i=1;i<=n;i++) a[i].x=read(),a[i].y=read(); sort(a+1,a+n+1); for (int i=1;i<=n;i++) { int x=a[i].y,t=i; while (t<n&&a[t+1].x<=x) t++,x=max(x,a[t].y); cnt++,b[cnt].x=a[i].x,b[cnt].y=x; i=t; } for (int i=1;i<cnt;i++) t++,c[t]=b[i].y-b[i].x,d[t]=b[i+1].x-b[i].y; c[++t]=b[cnt].y-b[cnt].x; for (int i=1;i<=t;i++) c[i]+=c[i-1]; for (int i=1;i<t;i++) d[i]+=d[i-1]; ans=c[1]+m; int x=0; for (int i=1;i<t;i++) { while (x+1<t&&d[x+1]-d[i-1]<m) x++; ans=max(ans,c[x+1]-c[i-1]+m); } cout<<ans; }View Code
E:容易發現任意一條邊的兩端總有一端包含最大值,先把這個判掉。不妨設n號點為樹根,此時考慮n-1號點,其與n號點的距離就應為n-1號點的出現次數。類似地發現構造一個鏈或者菊花就好了,構造完再判斷是否合法。n<=1000可能是為了寫起來舒服一點。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<‘0‘||c>‘9‘) {if (c==‘-‘) f=-1;c=getchar();} while (c>=‘0‘&&c<=‘9‘) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 1010 int n,a[N],b[N],cnt[N],tree[N],x; int main() { n=read(); for (int i=1;i<n;i++) { a[i]=read(),b[i]=read();cnt[a[i]]++; if (b[i]!=n) {printf("NO\n");return 0;} } tree[1]=n;x=1; for (int i=n-1;i;i--) if (cnt[i]) tree[x+=cnt[i]]=i; for (int i=n-1;i>=1;i--) if (!cnt[i]) for (int j=1;j<=n;j++) if (!tree[j]) {tree[j]=i;break;} for (int i=1;i<n;i++) { int x=0; for (int j=i+1;j<=n;j++) x=max(x,tree[j]); cnt[x]--; if (cnt[x]<0) {printf("NO\n");return 0;} } printf("YES\n"); for (int i=1;i<n;i++) cout<<tree[i]<<‘ ‘<<tree[i+1]<<endl; }View Code
F:比賽時看錯題了以為是找最長的交替等差子序列,這拿頭做啊。結束半個小時了才發現。考慮如何選取公差,若d=a*b且b是奇數,那麽d=a一定會更優。所以只枚舉2的冪次作為公差然後map存一下取模的結果就行了。註意ans初值設成2,因為可能存在橫坐標相同的點。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> #include<map> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<‘0‘||c>‘9‘) {if (c==‘-‘) f=-1;c=getchar();} while (c>=‘0‘&&c<=‘9‘) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 100010 int n,m,x,y,a[N],b[N],ans=2; map<int,int> f,g; int main() { n=read(),x=read(); for (int i=1;i<=n;i++) a[i]=read(); m=read(),y=read(); for (int i=1;i<=m;i++) b[i]=read(); for (int x=1;x<=1E9;x<<=1) { f.clear();g.clear(); for (int i=1;i<=n;i++) f[a[i]%(x<<1)]++; for (int i=1;i<=m;i++) g[b[i]%(x<<1)]++; for (int i=1;i<=n;i++) ans=max(ans,f[a[i]%(x<<1)]+g[(a[i]+x)%(x<<1)]); for (int i=1;i<=m;i++) ans=max(ans,g[b[i]%(x<<1)]+f[(b[i]+x)%(x<<1)]); } cout<<ans; }View Code
總體是一場readforces&speedforces。於是就翻車了。當然自己還是弱爆。
Codeforces Round#509 Div.2翻車記