A
给你 n k
然后第二行 n个数 其中有k个0 然后第三行 k个数
让k个数代替 0 问 能不能出现 非递增
k>=2 那么肯定可以出现 (数不一样)
k=1 那么 放进去 跑一下就可以
O(n)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<stdio.h> #include<algorithm> #include<string.h> using namespace std; #define inf 1000000007 #define MAXN 110 int z[MAXN]; int x[MAXN]; bool vis[250]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&z[i]); for(int j=1;j<=m;j++) { scanf("%d",&x[j]); vis[x[j]]++; } sort(x+1,x+m+1); int cnt=1; for(int i=1;i<=n;i++) if(z[i]==0) z[i]=x[cnt++]; int ok=0; for(int i=2;i<=n;i++) if(z[i]<=z[i-1]) ok=1; if(m>=2) ok=1; if(ok==1) printf("Yes\n"); else printf("No\n"); return 0; }
B
n
第二行 n个数 序列a
第三行n 个数 序列
原来有个序列p 其中数字是1~n的 a 序列 和p 有一个数是不同的 b 也有一个和 p不同 求p序列
a b 只有2中可能 1 一个不一样 2 2个不一样 列举下就可以
O(n ^2)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<stdio.h> #include<algorithm> #include<string.h> using namespace std; #define inf 1000000007 #define MAXN 1110 int z[MAXN],x[MAXN]; bool vis[MAXN]; int ind[5]; int ans[MAXN]; int main() { int n; while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++) scanf("%d",&z[i]); for(int i=1;i<=n;i++) scanf("%d",&x[i]); memset(vis,0,sizeof(vis)); int cnt=0; for(int i=1;i<=n;i++) { if(z[i]!=x[i]) { ind[cnt++]=i; } else { vis[z[i]]=1; ans[i]=z[i]; } } if(cnt==1) { for(int i=1;i<=n;i++) { if(vis[i]==0&&i!=z[ind[0]]&&i!=x[ind[0]]) { ans[ind[0]]=i; break; } } } else { int ok=0; for(int i=1;i<=n;i++) { if(vis[i]==1) continue; if(ok==1) break; for(int j=1;j<=n;j++) { if(i==j||vis[j]==1) continue; int cnt1=0,cnt2=0; if(i!=z[ind[0]]) cnt1++; if(i!=x[ind[0]]) cnt2++; if(j!=z[ind[1]]) cnt1++; if(j!=x[ind[1]]) cnt2++; if(cnt1==1&&cnt2==1) { ans[ind[0]]=i; ans[ind[1]]=j; ok=1; break; } cnt1=cnt2=0; if(j!=z[ind[0]]) cnt1++; if(j!=x[ind[0]]) cnt2++; if(i!=z[ind[1]]) cnt1++; if(i!=x[ind[1]]) cnt2++; if(cnt1==1&&cnt2==1) { ans[ind[1]]=i; ans[ind[0]]=j; ok=1; break; } } } } for(int i=1;i<n;i++) printf("%d ",ans[i]); printf("%d\n",ans[n]); } return 0; }
C
n
给你长度为n的字符串 都是小写的
然后m
m个查询
mi ci 可以改变字符串里面 mi个字母 求 最长的ci 的序列长度
要预处理下 ans[i][j] 表示 字母 为 ci 改变长度为 j 的 长度
x[i][j] 表示 没出现ci 的前缀和
列举26个字母
然后 列举开始的位子 列举长度 二分结束位子
O(26*n*n*log(n))
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<stdio.h> #include<algorithm> #include<string.h> using namespace std; #define inf 1000000007 #define MAXN 1110 char z[1520]; int x[27][1520]; int ans[27][1520]; int main() { int n; scanf("%d",&n); scanf("%s",z+1); for(int i=1;i<=26;i++) { for(int j=1;j<=n;j++) { if(z[j]-'a'==i-1) x[i][j]=x[i][j-1]; else x[i][j]=x[i][j-1]+1; } } for(int i=1;i<=26;i++) { for(int j=1;j<=n;j++)//� { for(int k=1;k<=n;k++)//���� { int l=j,r=n; int ind=j; while(l<=r) { int mid=(l+r)>>1; if(x[i][mid]-x[i][j-1]>k) r=mid-1; else { l=mid+1; ind=max(ind,mid); } } ans[i][k]=max(ans[i][k],ind-j+1); } } } int m; scanf("%d",&m); while(m--) { int a; char s[10]; scanf("%d %s",&a,s); printf("%d\n",ans[s[0]-'a'+1][a]); } return 0; }