0x18 总结与练习
这一章不太满意啊。。
还是有点痛苦,但就是做的挺慢啊。。。
1、就是例题
2、括号画家 感觉这种提高组类型的细节题都没什么信心啊,fail了几次才A
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; char ss[110000]; int top,sta[110000],sum[110000]; int main() { scanf("%s",ss+1);int len=strlen(ss+1); top=0;int mmax=0,nx=0; memset(sum,0,sizeof(sum)); for(int i=1;i<=len;i++) { if(ss[i]=='(')sta[++top]=0; else if(ss[i]=='[')sta[++top]=1; else if(ss[i]=='{')sta[++top]=2; else if(ss[i]==')') { if(top>0&&sta[top]==0) { sum[top-1]+=sum[top]+2; sum[top]=0,top--; nx=max(nx,sum[top]); } else { mmax=max(mmax,nx);nx=0; while(top>0)sum[top]=0,top--; sum[top]=0; } } else if(ss[i]==']') { if(top>0&&sta[top]==1) { sum[top-1]+=sum[top]+2; sum[top]=0,top--; nx=max(nx,sum[top]); } else { mmax=max(mmax,nx);nx=0; while(top>0)sum[top]=0,top--; sum[top]=0; } } else if(ss[i]=='}') { if(top>0&&sta[top]==2) { sum[top-1]+=sum[top]+2; sum[top]=0,top--; nx=max(nx,sum[top]); } else { mmax=max(mmax,nx);nx=0; while(top>0)sum[top]=0,top--; sum[top]=0; } } } printf("%d\n",max(mmax,nx)); return 0; }
3&&6、更加细节题,怂了
upd 完了表达式计算这种NOIP水题都写了这么久还fail了几发姿势很丑
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; const LL p=(1LL<<62); int quick_pow(int A,int p) { int ret=1; while(p!=0) { if(p%2==1)ret*=A; A*=A;p/=2; } return ret; } char ss[110]; int top,nxt[110],las;LL sta[110]; int readnum(int &i) { int ret=0; while('0'<=ss[i]&&ss[i]<='9') ret=ret*10+ss[i]-'0', i++; i--; return ret; } int t,s[110]; int solve(int l,int r) { t=0; if(sta[l+1]==p+2)sta[l+2]=-sta[l+2],l++; s[++t]=sta[l+1]; for(int i=l+3;i<=r-1;i+=2) { if(sta[i-1]>p+2) { if(sta[i-1]==p+3)s[t]=s[t]*sta[i]; if(sta[i-1]==p+4)s[t]=s[t]/sta[i]; if(sta[i-1]==p+5)s[t]=quick_pow(s[t],sta[i]); } else { if(sta[i-1]==p+1)s[++t]=sta[i]; if(sta[i-1]==p+2)s[++t]=-sta[i]; } } int ret=0; for(int i=1;i<=t;i++)ret+=s[i]; return ret; } int main() { scanf("%s",ss+2);int n=strlen(ss+2);n++; ss[1]='(';ss[++n]=')'; las=0;top=0; for(int i=1;i<=n;i++) { if('0'<=ss[i]&&ss[i]<='9')sta[++top]=readnum(i); else if(ss[i]=='(')sta[++top]=p, nxt[top]=las,las=top; else if(ss[i]=='+')sta[++top]=p+1; else if(ss[i]=='-')sta[++top]=p+2; else if(ss[i]=='*')sta[++top]=p+3; else if(ss[i]=='/')sta[++top]=p+4; else if(ss[i]=='^')sta[++top]=p+5; else if(ss[i]==')') { int r=top+1; top=las, sta[top]=solve(las,r), las=nxt[las]; } } printf("%d\n",sta[top]); return 0; }
4、poj1964 这个不就是2559嘛,枚举一下列就行了(鄙视rainbowcat卖狗粮)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int m,n,c[1100]; char ss[10]; void sc() { for(int i=1;i<=n;i++) { scanf("%s",ss+1); if(ss[1]=='R')c[i]=0; else c[i]++; } } int top,sta[1100],w[1100]; int solve() { int ret=0;c[n+1]=0; top=0;sta[++top]=1;w[top]=1; for(int i=2;i<=n+1;i++) { int L=0; while(top>0&&c[i]<=c[sta[top]]) { ret=max(ret,c[sta[top]]*(w[top]+L)); L+=w[top];top--; } sta[++top]=i;w[top]=L+1; } return ret*3; } int main() { int T; scanf("%d",&T); while(T--) { int mmax=0; scanf("%d%d",&m,&n); memset(c,0,sizeof(c)); for(int T=1;T<=m;T++) sc(), mmax=max(mmax,solve()); printf("%d\n",mmax); } return 0; }
5、这题都做到烂了
7、Matrix 这题真是做到人心态血崩。。。首先A是到100的,我就直接把每一列长度为A的区间用两个long long存,然后xjb hash前10位弄个hash表,结果这狗逼数据居然故意卡我,弄个全是0的矩阵询问还只有最后一位1,然后我也很不要脸的把后10位hash了做。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; char ss[1100][1100],sc[1100][1100]; LL zt[1100][1100][2],hh[1100][2]; int n,m,A,B; int nxt[1100000],last[1100000]; int point(int x,int y){return (x-1)*m+y;} int main() { scanf("%d%d%d%d",&n,&m,&A,&B); for(int i=1;i<=n;i++)scanf("%s",ss[i]+1); memset(zt,0,sizeof(zt)); for(int i=1;i<=n-A+1;i++) for(int j=1;j<=m;j++) for(int k=1;k<=A;k++) { LL x=ss[i+k-1][j]-'0'; if(k<=50)zt[i][j][0]+=(x<<(k-1)); else zt[i][j][1]+=(x<<(k-51)); } for(int i=1;i<=n-A+1;i++) for(int j=1;j<=m-B+1;j++) { int p=point(i,j);LL ke=0; int li=min(B,10); for(int k=B-li+1;k<=B;k++) { LL d=(zt[i][j+k-1][0]*7+zt[i][j+k-1][1])%1000019; ke=(ke*93+d)%1000019; } nxt[p]=last[ke]; last[ke]=p; } int Q; scanf("%d",&Q); while(Q--) { for(int i=1;i<=A;i++)scanf("%s",sc[i]+1); memset(hh,0,sizeof(hh)); for(int j=1;j<=B;j++) for(int i=1;i<=A;i++) { LL x=sc[i][j]-'0'; if(i<=50)hh[j][0]+=(x<<(i-1)); else hh[j][1]+=(x<<(i-51)); } LL ke=0;int li=min(B,10); for(int k=B-li+1;k<=B;k++) { LL d=(hh[k][0]*7+hh[k][1])%1000019; ke=(ke*93+d)%1000019; } int QAQ=0; for(int k=last[ke];k;k=nxt[k]) { int x,y; y=(k%m==0)?m:k%m; x=(k-y)/m+1; bool bk=true; for(int j=1;j<=B;j++) if(hh[j][0]!=zt[x][y+j-1][0]|| hh[j][1]!=zt[x][y+j-1][1]) {bk=false;break;} if(bk==true){QAQ=1;break;} } printf("%d\n",QAQ); } return 0; }
8、做KMP那章的时候没有最小表示法的例题,就随便找了道,结果就是这个0x15 KMP
9、poj2185 先把行hash,然后做kmp求循环节,同样把列这样搞一次,乘起来就行了
contest hunter里面还有道EXKMP的,懒得复习了zzz
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int n,m; char ss[11000][110]; int ha[11000]; bool check(int x,int y) { if(ha[x]!=ha[y])return false; for(int j=1;j<=m;j++) if(ss[x][j]!=ss[y][j])return false; return true; } bool check2(int x,int y) { if(ha[x]!=ha[y])return false; for(int i=1;i<=n;i++) if(ss[i][x]!=ss[i][y])return false; return true; } int p[11000]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%s",ss[i]+1); for(int i=1;i<=n;i++) { ha[i]=0; for(int j=1;j<=m;j++) ha[i]=(ha[i]*47+(ss[i][j]-'A'+1))%1000019; } p[1]=0;int j=0; for(int i=2;i<=n;i++) { while(j>0&&check(i,j+1)==false)j=p[j]; if(check(i,j+1)==true)j++; p[i]=j; } int d1=n-p[n]; for(int j=1;j<=m;j++) { ha[j]=0; for(int i=1;i<=n;i++) ha[j]=(ha[j]*47+(ss[i][j]-'A'+1))%1000019; } p[1]=0;j=0; for(int i=2;i<=m;i++) { while(j>0&&check2(i,j+1)==false)j=p[j]; if(check2(i,j+1)==true)j++; p[i]=j; } int d2=m-p[m]; printf("%d\n",d1*d2); return 0; }
10、poj3630 水
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; struct Trie { int w[30];bool b; Trie(){} void clean(){b=false;memset(w,0,sizeof(w));} }tr[1100000];int trlen; char ss[1100000]; bool maketree() { int now=0,len=strlen(ss+1);bool bk=false; for(int i=1;i<=len;i++) { int x=ss[i]-'0'; if(tr[now].w[x]==0) tr[now].w[x]=++trlen, tr[trlen].clean(), bk=true; now=tr[now].w[x]; if(tr[now].b==true){bk=false;break;} } tr[now].b=true; return bk; } int main() { int T; scanf("%d",&T); while(T--) { int n;bool qwq=true; scanf("%d",&n); trlen=0;tr[trlen].clean(); for(int i=1;i<=n;i++) { scanf("%s",ss+1); if(qwq==true)qwq=maketree(); } if(qwq==true)printf("YES\n"); else printf("NO\n"); } return 0; }
11、poj1442 难度在题意。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> using namespace std; int a[31000],b[31000]; priority_queue<int,vector<int>,greater<int> >q; priority_queue<int>d; int main() { int n,m,ti,tp=1; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<=m;i++) { scanf("%d",&ti); while(tp<=n&&tp<=ti) { d.push(a[tp]);tp++; q.push(d.top());d.pop(); } printf("%d\n",q.top()); d.push(q.top()),q.pop(); } return 0; }
pain and happy in the cruel world.