A:水题不懂的看下代码就懂了
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int mx = 2e6+100;
int n,m,q;
int main(){
while(~scanf("%d%d%d",&n,&m,&q)){
int ans = 0,cnt = 0,v;
while(n--){
scanf("%d",&v);
if(v==1){
if(m==0){
if(q==0){
if(cnt) cnt--;
else ans+=v;
}else{
q--;
cnt++;
}
}else m--;
}else{
if(q==0) ans+=v;
else q--;
}
}
printf("%d\n",ans);
}
return 0;
}
B题:找到最低最高最左最右差值取max比较一下。代码写的比较丑
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int mx = 1e2+100;
int n,m,q;
char str[mx][mx];
int main(){
while(~scanf("%d%d%d",&n,&m)){
int high=0,low=0,right=0,left=0,cnt = 0;
for(int i=0;i<n;i++){
scanf("%s",str[i]);
for(int j=0;j<m;j++)
if(str[i][j]=='B') cnt++;
}
for(int i=0;!high&&i<n;i++)
for(int j=0;!high&&j<m;j++)
if(str[i][j]=='B') high = i+1;
for(int i=n-1;!low&&i>=0;i--)
for(int j=0;!low&&j<m;j++)
if(str[i][j]=='B') low = i+1;
for(int j=0;!left&&j<m;j++)
for(int i=0;!left&&i<n;i++)
if(str[i][j]=='B') left = j+1;
for(int j=m-1;!right&&j>=0;j--)
for(int i=0;!right&&i<n;i++)
if(str[i][j]=='B') right = j+1;
int maxx=max(right-left,low-high)+1;
if(!cnt) puts("1");
else if(maxx>min(n,m)) puts("-1");
else printf("%d\n",maxx*maxx-cnt);
}
return 0;
}
C题:
并查集维护没有填入的点就行了。
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int mx = 3e6+100;
int n,m,q,f[mx];
char str[mx],ans[mx];
int find(int x){
return x==f[x]? x:f[x]=find(f[x]);
}
int main(){
while(~scanf("%d",&n)){
memset(ans,'a',sizeof(ans));
for(int i=1;i<mx;i++) f[i]=i;
int maxx = 0;
while(n--){
scanf("%s%d",str,&m);
int len = strlen(str);
while(m--){
scanf("%d",&q);
maxx = max(q+len,maxx);
for(int i=find(q);i<q+len;i=f[i]=find(i+1))
ans[i] = str[i-q];
}
}
ans[maxx] = '\0';
puts(ans+1);
}
return 0;
}
D题:创建一个父节点,让他有m个孩子节点,然后m个孩子的孩子个只延伸一个。这就是最优方案。然后求节点高度就行了。
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int mx = 2e6+100;
int n,m,q;
int main(){
while(~scanf("%d%d",&n,&m)){
int k =(n-1)/m,mod = (n-1)%m;
if(mod>=2) k = 2*(k+1);
else if(mod==1) k = 2*k+1;
else k = 2*k;
printf("%d\n",k);
for(int i=2;i<=m+1;i++) printf("1 %d\n",i);
int j = m+2;
for(int i=2;j<=n;j++,i++){
printf("%d %d\n",i,j);
}
}
return 0;
}
E题:我们发现e字符串很短也就是某个i点能向后延伸1-10个步长。延伸的起点也只可能是1-10这前十个点。又有4个字母那么我们应该需要维护的是一个sum[x][y][z][q],代表起点,步长,哪个字母,从该起点以这种步长走到q有了几个z字母。数组大小差不多为sum【11】【11】【4】【10^5+10】,然后就是树状数组维护就行了,不会很麻烦。
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int mx = 1e5+10;
int n,m,q;
int sum[11][11][4][mx],lens;
char str[mx],c[20];
inline int lowbit(int x){
return x&(-x);
}
int getnum(char c1){
switch(c1){
case 'A':return 0;
case 'T':return 1;
case 'G':return 2;
case 'C':return 3;
}
}
void add(int s,int x,int y,int z,int v){
for(int i = s;i<=lens;i+=lowbit(i))
sum[x][y][z][i] += v;
}
void update(int x,int k,int v){
for(int j=1;j<=10;j++){
int p = x%j;
if(!p) p = j;
add(x,p,j,k,v);
}
}
int query(int x,int y,int k,int s){
int ans = 0;
while(s){
ans+=sum[x][y][k][s];
s-=lowbit(s);
}
return ans;
}
int main(){
while(~scanf("%s",str+1)){
memset(sum,0,sizeof(sum));
scanf("%d",&n);
lens = strlen(str+1);
for(int i=1;i<=lens;i++){
int k = getnum(str[i]);
update(i,k,1);
}
int x,y,z;
while(n--){
scanf("%d",&x);
if(x==1){
scanf("%d%s",&y,c);
update(y,getnum(str[y]),-1);
update(y,getnum(c[0]),1);
str[y] = c[0];
}else{
scanf("%d%d%s",&y,&z,c);
int len = strlen(c),ans = 0;
for(int i=0;i<len;i++){
int p = (i+y)%len;
if(!p) p = len;
ans += query(p,len,getnum(c[i]),z)-query(p,len,getnum(c[i]),y-1);
}
printf("%d\n",ans);
}
}
}
return 0;
}