题目传送门

A 切数字乘法

B 合并班级

C 彩彩玩跳棋

D 彩彩玩扫雷

T1切数字乘法

思路

直接暴力枚举数位分离

代码

#include<bits/stdc++.h>
using namespace std;

int main(){
	freopen("num.in","r",stdin);
	freopen("num.out","w",stdout);
	unsigned long long int n,x,y,z,w=0,h=1,ma=0;
	cin>>n;
	z=n;
	while(z){
		z/=10;
		w++;
		h*=10;
	}
	h/=10;
	x=0;
	y=n;
	for(unsigned long long int i=1;i<w;i++,h/=10){
		x=n/h;
		y=n%h;
		ma=max(ma,x*y);
	}
	cout<<ma;
}

T2合并班级

思路

结构体排序来做就可以了

思路

#include<bits/stdc++.h>
using namespace std;
long long n,m,st[100010],ss[100010];
struct P{
	long long cj,id;
}a[100010],b[100010];
bool cmp(P a,P b){
	return a.cj>b.cj;
}
int main(){
	freopen("class.in","r",stdin);
	freopen("class.out","w",stdout);
	cin>>n>>m;
	for(long long i=1;i<=n;i++)cin>>a[i].cj,a[i].id=i;
	for(long long i=1;i<=m;i++)cin>>b[i].cj,b[i].id=i;
	sort(a+1,a+1+n,cmp);
	sort(b+1,b+1+m,cmp);
	long long s=-100,mm=-100;
	for(long long i=1;i<=n;i++){
		if(a[i].cj==s)st[a[i].id]=mm;
		else st[a[i].id]=i;
		s=a[i].cj;
		mm=st[a[i].id];
	}
	s=-100,mm=-100;
	for(long long i=1;i<=m;i++){
		if(b[i].cj==s)ss[b[i].id]=mm;
		else ss[b[i].id]=i;
		s=b[i].cj;
		mm=ss[b[i].id];
	}
	s=-100,mm=-100;
	long long i=1,j=1,c=1,w=0;
	for(;i<=n&&j<=m;c++){
		long long xz,yc,zm,bj;
		if(a[i].cj>b[j].cj)xz=a[i].cj,bj=0,yc=st[a[i].id];
		else xz=b[j].cj,yc=ss[b[j].id],bj=1;
		if(xz==s)zm=mm;
		else zm=c;
		mm=zm;
		s=xz;
		w+=(yc-zm)*(yc-zm);
		if(bj==0)i++;
		else j++;
	}
	while(i<=n){
		long long xz,yc,zm;
		xz=a[i].cj,yc=st[a[i].id];
		if(xz==s)zm=mm;
		else zm=c;
		mm=zm;
		s=xz;
		w+=(yc-zm)*(yc-zm);
		i++;
		c++;
	}
	while(j<=m){
		long long xz,yc,zm;
		xz=b[j].cj,yc=ss[b[j].id];
		if(xz==s)zm=mm;
		else zm=c;
		mm=zm;
		s=xz;
		w+=(yc-zm)*(yc-zm);
		j++;
		c++;
	}
	cout<<w;
	return 0;	
}

T3彩彩玩跳棋

思路

我们先提前将第ii个格子前第一个棋子表示为a[i]a[i],然后用f[i]f[i]表示第ii各个子能跳多少,然后循环,定义一个d=ia[i]d=i-a[i]如果a[i]d>a[i1]a[i]!=ia[i]-d>a[i-1]且a[i]!=i那么f[i]=f[a[i]]d+d2f[i]=f[a[i]]-d+d*2最后输出最大值

代码

#include<bits/stdc++.h>
using namespace std;
int n,m,a[200010],f[200010],mx;
int main(){
	freopen("chess.in","r",stdin);
	freopen("chess.out","w",stdout);
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int x;
		cin>>x;
		a[x]++;
	}
	for(int i=1;i<=n;i++){
		if(!a[i])a[i]=a[i-1];
		else a[i]=i;
	}
	for(int i=1;i<=n;i++){
		if(a[i]==i)continue;
		int d=i-a[i];
		if(a[i]-d<=0)continue;
		if(a[i]-d<=a[a[i]-1])continue;
		f[i]=f[a[i]-d]+d*2;
		mx=max(mx,f[i]);
	}
	cout<<mx;
	return 0;	
}

错的点

用搜索写但写错了,以后要多多向更好的办法

T4彩彩玩扫雷

思路

利用去皮雪芙距离来写,就是一个差分模板了,但要注意负数坐标

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int f[5555][5555],n,m;
void zf(int x1,int y1,int x2,int y2){
	f[x1][y1]++;
	f[x2+1][y1]--;
	f[x1][y2+1]--;
	f[x2+1][y2+1]++;
}
signed main(){
	freopen("game.in","r",stdin);
	freopen("game.out","w",stdout);
	cin>>n>>m;
	while(m--){
		int x,y,b;
		cin>>x>>y>>b;
		int x1=(x+y);
		int y1=(x-y)+1000;
		zf(max(1ll,x1-b),max(1ll,y1-b),min(3000ll,x1+b),min(3000ll,y1+b));
	}
	for(int i=1;i<=3000;i++)for(int j=1;j<=3000;j++){f[i][j]+=f[i][j-1]+f[i-1][j]-f[i-1][j-1];}
	int q;
	cin>>q;
	while(q--){
		int x,y;
		cin>>x>>y;
		int x1=(x+y);
		int y1=(x-y)+1000;
		cout<<f[x1][y1]<<"\n";
	}		
}

错的点

骗了分,以后要认真想正解