A dp
吃了 (x,y)的豆子 就不能吃x-1 x+1 行 还有 (x,y-1),(x,y+1) 的豆子
求最大 果然是菜菜 第1 先想怎么求得一行的最大的 ->>>>> 就是求最大不连续的和dp[i]=max(dp[i-1],dp[i-2]+w[i]);
那么整个矩阵呢 把上面处理出来每一行最大的 求一个最大不连续的和
#include<stdio.h> #include<algorithm> #include<string.h> #include<iostream> #include<math.h> #include<queue> using namespace std; #define MAXN 200010 #define inf 1000000007 #define ll long long int z[MAXN]; int dp[MAXN]; int sum[MAXN]; int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) scanf("%d",&z[j]); dp[0]=0; dp[1]=z[1]; int mx=dp[1]; for(int j=2;j<=m;j++) { dp[j]=max(dp[j-2]+z[j],dp[j-1]); mx=max(mx,dp[j]); } sum[i]=mx; } int mx=0; dp[0]=0; dp[1]=sum[1]; mx=dp[1]; for(int j=2;j<=n;j++) { dp[j]=max(dp[j-2]+sum[j],dp[j-1]); mx=max(mx,dp[j]); } printf("%d ",mx); } return 0; }
H
n 然后n个操作 操作有3种
0 a 插入 a
1 a 删除 a 如果a存在的话 不存在输出 No Elment!
2 a k 查询比a大的 第k个 不存在输出 Not Find!
0 1
只是线段树的单点更新 不多说
那么 查询比a大第k个 我是 先查了a在第x个 然后只要在树上查第 x+k 有没有就可以了
#include<stdio.h> #include<algorithm> #include<string.h> #include<iostream> #include<math.h> #include<queue> using namespace std; #define MAXN 100010 #define inf 1000000007 #define ll long long struct node { int l,r,w; }tree[MAXN<<2]; int ok; void Build(int l,int r,int a) { tree[a].l=l; tree[a].r=r; tree[a].w=0; if(l==r) return ; int mid=(l+r)>>1; Build(l,mid,a<<1); Build(mid+1,r,a<<1|1); } void Update(int l,int r,int a1,int a) { if(l==r) { tree[a].w=tree[a].w+1; return ; } int mid=(l+r)>>1; if(a1<=mid) Update(l,mid,a1,a<<1); else Update(mid+1,r,a1,a<<1|1); tree[a].w=tree[a<<1].w+tree[a<<1|1].w; } void Delete(int l,int r,int a1,int a) { if(l==r) { if(tree[a].w==0) ok=1; else tree[a].w=tree[a].w-1; return ; } int mid=(l+r)>>1; if(a1<=mid) Delete(l,mid,a1,a<<1); else Delete(mid+1,r,a1,a<<1|1); tree[a].w=tree[a<<1].w+tree[a<<1|1].w; } int Ques(int l,int r,int k,int a) { if(l==r) return l; int mid=(l+r)>>1; if(k>tree[a<<1].w) { return Ques(mid+1,r,k-tree[a<<1].w,a<<1|1); } else { return Ques(l,mid,k,a<<1); } } int Ques1(int l,int r,int a1,int b1,int a) { if(a1<=l&&r<=b1) return tree[a].w; int ans=0; int mid=(l+r)>>1; if(a1<=mid) ans=ans+Ques1(l,mid,a1,b1,a<<1); if(b1>mid) ans=ans+Ques1(mid+1,r,a1,b1,a<<1|1); return ans; } int main() { int n; int r=100000; while(scanf("%d",&n)!=EOF) { Build(1,r,1); while(n--) { int type; scanf("%d",&type); if(type==0) { int a; scanf("%d",&a); Update(1,r,a,1); } else if(type==1) { int a; scanf("%d",&a); ok=0; Delete(1,r,a,1); // printf("%d ",ok); if(ok==1) printf("No Elment! "); } else { int a,k; ok=0; scanf("%d%d",&a,&k); int c=Ques1(1,r,1,a,1); k=k+c; if(k>tree[1].w) { printf("Not Find! "); continue; } int ans=Ques(1,r,k,1); printf("%d ",ans); } } } return 0; }
B
n然后 n个串
m然后m个串 问上面有多少个串包括下面这个串 输出m个数字
n个串建字典树 abab 那么就是 abab bab ab b 但是不能重复计数 那么 加上个标记就行了
#include<stdio.h> #include<algorithm> #include<string.h> #include<iostream> #include<math.h> #include<queue> #include<stdlib.h> using namespace std; #define MAXN 100010 #define inf 1000000007 #define ll long long char s[25]; struct node { int cnt,id; struct node *next[27]; void cl() { memset(next,0,sizeof(next)); cnt=1; } }; int ok; void Insert(char *s,struct node *p,int cou) { while(*s) { int a=*s-'a'; if(p->next[a]==0) { p->next[a]=(struct node *)malloc(sizeof(struct node)); (p->next[a])->cl(); (p->next[a])->id=cou; } p=p->next[a]; if(p->id!=cou) { (p->cnt)++; p->id=cou; } s++; } } int Ques(char *s,struct node *p) { int len=strlen(s); for(int i=0;i<len;i++) { int a=s[i]-'a'; if(p->next[a]) p=p->next[a]; else return 0; } return p->cnt; } int main() { int n,m; scanf("%d",&n); struct node * root; root=(struct node *)malloc(sizeof(struct node)); root->cl(); int cou=1; for(int i=1;i<=n;i++) { scanf("%s",s); ok=0; int len=strlen(s); for(int j=0;j<len;j++) { Insert(s+j,root,cou); ok=1; } cou++; } scanf("%d",&m); for(int i=1;i<=m;i++) { int ans=0; scanf("%s",s); ans=Ques(s,root); printf("%d ",ans); } return 0; }
C
给你一个2进制字符串a 然后一个数b 要求在这个字符串上补0或者1 使得b能整除a 求长度最小 字典序最小 不可能输出impossibl
显然是可能的 至少可以在最后加上b 然后 最多就是2^20次方 直接跑的 然后求一下列举的b的倍数是不是包含a就可以了 a=0注意下
#include<stdio.h> #include<algorithm> #include<string.h> #include<iostream> #include<math.h> #include<queue> #include<stdlib.h> using namespace std; #define MAXN 100010 #define inf 1000000007 #define ll long long char z[35]; char s[35]; int main() { while(scanf("%s",z)!=EOF) { int a; scanf("%d",&a); int b=0; int len=strlen(z); for(int i=0;i<len;i++) b=b*2+z[i]-'0'; if(b%a==0) { printf("%d ",b); continue; } for(int i=1;;i++) { int c=a*i; int cnt=0; int d=c; while(d) { s[cnt++]=d%2+'0'; d=d/2; } for(int j=0;j<(cnt+1)/2;j++) swap(s[j],s[cnt-j-1]); int c1,c2; s[cnt]='