Codeforces Round #156 (Div. 2)
爱到深处伤到死,没死继续codeforces.
a. 简单模拟题、
b. 统计字符串中x,y的个数,输出的为然后一个x抵消一个y,输出剩下的.
c. dp题, 这个状态转移以前没有见过,学习了下. 还有这题用其他的O(N*N)的算法,步骤不能太多容易超时,比赛的时候就写了一种 n*n 的超时算法。
记得以前做的dp题,每次状态转移时都是根据固定的前面一层转移到这层. 而这次这个dp是连之前的也一起改变, 也就是当save[i]==save[j] 的时候 然后就让id=j . 具体看代码
#include <stdio.h> #include <string.h> #include <iostream> using namespace std; #define N 4004 int g[N]; int dp[N][N]; int main() { int n; scanf("%d",&n); int mx=-1; for(int i=1;i<=n;i++) { scanf("%d",&g[i]); int id; for(int j=id=0;j<i;j++) { dp[i][j]=dp[j][id]+1; if(g[i]==g[j]) id=j; if(dp[i][j]>mx) mx=dp[i][j]; } } printf("%d",mx); return 0; }
d. 二分搜索题, 题目的关键在于求 在进行了n秒后,覆盖的格子数, 根据扩张的规律可以得出。 还要注意不要超出范围
#include <stdio.h> #include <string.h> #include <iostream> using namespace std; typedef __int64 LL; LL n,x,y,c; int fuc(LL s) { LL sum=0; LL u,d,r,l; u=min(s,x-1); d=min(s,n-x); l=min(s,y-1); r=min(s,n-y); LL a1=(s-1); LL an=a1-(r-1); if(u+r<=s) sum+=u*r; else { sum += (a1+an)*r/2; LL tmpu=s-u; if(tmpu-1<=r) sum -= tmpu*(tmpu-1)/2; else sum -= ((tmpu-1)+(tmpu-1-r+1))*r/2; } if(r+d<=s) sum+=r*d; else { sum += (a1+an)*r/2; LL tmpd=s-d; if(tmpd-1<=r) sum-=tmpd*(tmpd-1)/2; else sum-=((tmpd-1)+(tmpd-1-r+1))*r/2; } an=a1-(l-1); if(u+l<=s) sum+=u*l; else { LL tmpu=s-u; sum+=(a1+an)*l/2; if(tmpu-1<=l) sum-=(tmpu)*(tmpu-1)/2; else { sum-=((tmpu-1)+(tmpu-1-l+1))*l/2; } } if(d+l<=s) sum+=d*l; else { LL tmpd=s-d; sum+=(a1+an)*l/2; if(tmpd-1<=l) sum-=tmpd*(tmpd-1)/2; else { sum-=((tmpd-1)+(tmpd-1-l+1))*l/2; } } sum=sum+u+d+r+l+1; if(sum>=c) return 1; else return 0; } int main() { scanf("%I64d%I64d%I64d%I64d",&n,&x,&y,&c); if(c==1) { printf("0"); return 0; } LL b=0; LL d=n*n; while(b<d) { LL mid=(b+d)/2; if(fuc(mid)==1) { d=mid; } else b=mid+1; } printf("%I64d",b); return 0; }