这场比赛切了 A ~ D,然后 E WA on test 32,考试后特判了一个边界就过了.
感觉打得还行,但是没有在考试中 AC E 题实属可惜.
A Shovels and Swords
日常被 div2 A 题卡住.jpg
开始写了一个不知道对不对的贪心过不了样例,然后猜了一个小结论(a+b)/3,就过了.
#include <bits/stdc++.h> #define ll long long #define setIO(s) freopen(s".in","r",stdin) using namespace std; void solve() { int a,b; scanf("%d%d",&a,&b); if(a>b) swap(a,b); if(a*2<=b) printf("%d ",a); else { printf("%d ",(a+b)/3); } } int main() { // setIO("input"); int T; scanf("%d",&T); while(T--) solve(); return 0; }
B Shuffle
由于起点固定,所以可以到达的地方一定是一个连续区间,然后维护这个极大区间就行了.
#include <bits/stdc++.h> #define ll long long #define setIO(s) freopen(s".in","r",stdin) using namespace std; void solve() { int n,m,x,L,R; scanf("%d%d%d",&n,&x,&m); L=R=x; for(int i=1;i<=m;++i) { int l,r; scanf("%d%d",&l,&r); if((r>=L&&r<=R)||(l>=L&&l<=R)||(L>=l&&L<=r)||(R>=l&&R<=r)) { L=min(L,l); R=max(r,R); } } printf("%d ",R-L+1); } int main() { // setIO("input"); int T; scanf("%d",&T); while(T--) solve(); return 0; }
C Palindromic Paths
画一画图,发现所有从起点走 i 步能到达的格子和从终点走 i 步能到达的格子必须颜色相同.
按照这个步数统计一下颜色个数然后取 min 就行了.
#include <bits/stdc++.h> #define ll long long #define setIO(s) freopen(s".in","r",stdin) using namespace std; int a[40][40]; int bu1[100][2],bu2[100][2]; void solve() { int n,m; scanf("%d%d",&n,&m); memset(bu1,0,sizeof(bu1)); memset(bu2,0,sizeof(bu2)); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) scanf("%d",&a[i][j]); int flag=0; if((n+m-2)%2==0) flag=1; for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) { bu1[i+j-2][a[i][j]]++; bu2[n-i+m-j][a[i][j]]++; } } int half=(n+m-2)%2==0?(n+m-2)/2-1:(n+m-2)/2; int ans=0; // printf("%d ",half); for(int i=0;i<=half;++i) { ans+=min(bu1[i][0]+bu2[i][0],bu1[i][1]+bu2[i][1]); } printf("%d ",ans); } int main() { // setIO("input"); int T; scanf("%d",&T); while(T--) solve(); return 0; }
D Two Divisors
要求同时满足 $a|A$, $b|A$, gcd(a+b,A)=1.
如果想满足第二个条件的话 $a,b$ 必须互质,就得出 $gcd(a+b,a)=gcd(a+b,b)=gcd(a+b,A)=1$ 的结论.
当然,考场上没有推结论,猜到这个结论后交了一发就过了.
#include <bits/stdc++.h> #define N 10000008 #define ll long long #define INF 10000000 #define M 500008 #define setIO(s) freopen(s".in","r",stdin) using namespace std; int n; int a[M],b[M],L[M],R[M]; bool is[N],vis[N]; vector<int>g[N]; int main() { // setIO("input"); scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]),b[i]=a[i],vis[a[i]]=1; for(int i=2;i<=INF;++i) { if(is[i]) continue; for(int j=i+i;j<=INF;j+=i) { if(vis[j]) g[j].push_back(i); is[j]=1; } } for(int i=1;i<=n;++i) { int x=a[i]; for(int j=0;j<g[x].size();++j) { int p=g[x][j]; if(!is[p]) { int q=a[i]; while(q%p==0) q/=p; if(q!=1) { L[i]=p,R[i]=q; break; } } } if(!L[i]) L[i]=R[i]=-1; } for(int i=1;i<=n;++i) printf("%d ",L[i]); printf(" "); for(int i=1;i<=n;++i) printf("%d ",R[i]); return 0; }
E Two Arrays
这道题调出来该多好呀,估计能涨不少分QAQ...
#include <bits/stdc++.h> #define ll long long #define mod 998244353 #define N 400009 #define setIO(s) freopen(s".in","r",stdin) using namespace std; stack<int>S; int a[N],b[N],A[N<<1],mp[N<<1],R[N],L[N],f[N],n,m,cnt; void init() { S.push(1); L[1]=1; for(int i=2;i<=n;++i) { while(!S.empty() && a[S.top()]>=a[i]) S.pop(); L[i]=S.empty()?1:S.top()+1; S.push(i); } } int main() { // setIO("input"); scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) { scanf("%d",&a[i]); A[++cnt]=a[i]; } for(int i=1;i<=m;++i) { scanf("%d",&b[i]); A[++cnt]=b[i]; } sort(A+1,A+1+cnt); for(int i=1;i<=n;++i) { a[i]=lower_bound(A+1,A+1+cnt,a[i])-A-1; } for(int i=1;i<=m;++i) { b[i]=lower_bound(A+1,A+1+cnt,b[i])-A-1; mp[b[i]]=i; } init(); f[0]=1; for(int i=1;i<=n;++i) if(mp[a[i]]==1&&L[i]==1) f[i]=1,R[i]=1; for(int i=1;i<=n;++i) { if(mp[a[i]]>1) { R[i]=mp[a[i]]; int k=mp[a[i]]; int lst=L[i]-1; if(R[lst]==k-1) (f[i]+=(ll)f[lst]*(i-lst)%mod)%=mod; } else { if(!mp[a[i]]&&i!=1) { if(b[R[i-1]]<a[i]) f[i]=f[i-1],R[i]=R[i-1]; } } } printf("%d ",R[n]==m?f[n]:0); return 0; }