2023/3/4天梯备战acwing刷题

796子矩阵的和

二维前缀和

#include<iostream>
using namespace std;
const int maxx = 1e3+10;
int ma[maxx][maxx];

int main(){
	int n,m,q;
	cin>>n>>m>>q;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>ma[i][j];
			ma[i][j]=ma[i-1][j]+ma[i][j-1]-ma[i-1][j-1]+ma[i][j];
		}
	}
	while(q--){
		int x1,x2,y1,y2;
		cin>>x1>>y1>>x2>>y2;
		cout<<ma[x2][y2]-ma[x1-1][y2]-ma[x2][y1-1]+ma[x1-1][y1-1]<<endl;
	}
	return 0;
}

1096地牢大师

bfs模板

#include<iostream>
#include<queue>
using namespace std;

string m[110][110];
int dir[6][3] = {{0,0,1},{0,1,0},{1,0,0},{0,0,-1},{0,-1,0},{-1,0,0}};

int L,R,C;
int sl,sr,sc;

struct Node{
	int l;
	int r;
	int c;
	int step;
};

int bfs(){
	Node cur={sl,sr,sc,0};
	queue<Node> q;
	q.push(cur);
	while(q.size()){
		Node pre = q.front();
		q.pop();
		for(int i=0;i<6;i++){
			int nexl = pre.l+dir[i][0];
			int nexr = pre.r+dir[i][1];
			int nexc = pre.c+dir[i][2];
			int nexStep = pre.step+1;
			if(nexl==L||nexl<0||nexr==R||nexr<0||nexc==C||nexc<0){
				continue;
			}
			if(m[nexl][nexr][nexc]=='#'){
				continue;
			}
			if(m[nexl][nexr][nexc]=='.'){
				Node nex = {nexl,nexr,nexc,nexStep};
				q.push(nex);
				m[nexl][nexr][nexc] = '#';
			}
			if(m[nexl][nexr][nexc]=='E'){
				return nexStep;
			}
		}
	}
	return -1;
}

int main(){
	while(true){
		cin>>L>>R>>C;
		if(L==0){
			break;
		}
		getchar();
		for(int i=0;i<L;i++){
			for(int j=0;j<R;j++){
				getline(cin,m[i][j]);
			}
			string tmp;
			getline(cin,tmp);
		}
		for(int i=0;i<L;i++){
			for(int j=0;j<R;j++){
				for(int k=0;k<C;k++){
					if(m[i][j][k]=='S'){
						sl=i;
						sr=j;
						sc=k;
					}
				}
			}
		}
		int res = bfs();
		if(res == -1){
			cout<<"Trapped!"<<endl;
		}else{
			printf("Escaped in %d minute(s).\n",res);
		}
	}
	return 0;
}

1224交换瓶子

很巧妙的思路,在遍历时不是让a[j]复原,而是让a[a[j]]复原
1 e 4 1e4 1e4的时间复杂度也够用

#include<iostream>
using namespace std;
const int maxx = 1e4+10;

int a[maxx];

int main(){
	int N;
	cin>>N;
	for(int i=1;i<=N;i++){
		cin>>a[i];
	}
	bool res = false;
	int ans = 0;
	for(int i=1;i<=N;i++){
		for(int j=1;j<=N;j++){
			if(a[j]!=j){
				swap(a[j],a[a[j]]);
				ans++;
			}
		}
	}
	cout<<ans<<endl;
	return 0;
}

1240完全二叉树的权值

使用数组模拟完全二叉树,注意完全二叉树的性质,即
首先根节点的下标为 1 ,层数从 1 开始 首先根节点的下标为1,层数从1开始 首先根节点的下标为1,层数从1开始
对于第 i 层,结点下标为 [ 2 i − 1 , 2 i − 1 ] 对于第i层,结点下标为[2^{i-1},2^i-1] 对于第i层,结点下标为[2i1,2i1]

#include<cmath>
#include<iostream>
using namespace std;
const int maxx = 1e5+10;
typedef long long ll;

int main(){
	int N;
	cin>>N;
	int a[maxx];
	for(int i=1;i<=N;i++){
		cin>>a[i];
	}
	int maxd = (int)(log(N)/log(2))+1;
	ll maxsum = -1e10-10;
	//2^(n-1)~2^n-1
	int ans = 1;
	for(int i=1;i<=maxd;i++){
		ll sum = 0;
		for(int j=(int)pow(2,i-1);j<=(int)pow(2,i)-1 && j<=N;j++){
			sum+=a[j];
		}
		if(maxsum<sum){
			maxsum=sum;
			ans = i;
		}
	}
	cout<<ans<<endl;
	return 0;
}

895最长上升子序列

模板中的模板

#include<iostream>
using namespace std;

const int maxx = 1e3+100;

int a[maxx];
int dp[maxx];

int main(){
	int N;
	cin>>N;
	for(int i=0;i<N;i++){
		cin>>a[i];
	}
	int ans = 0;
	for(int i=0;i<N;i++){
		for(int j=0;j<i;j++){
			if(a[i]>a[j]){
				dp[i]=max(dp[i],dp[j]+1);
				ans = max(ans,dp[i]);
			}
		}
	}
	cout<<ans+1<<endl;
	return 0;
}

1015摘花生

dp模板

#include<iostream>
using namespace std;
const int maxx = 110;

int m[maxx][maxx];
int main(){
	int T;
	cin>>T;
	while(T--){
		int R,C;
		cin>>R>>C;
		for(int r=1;r<=R;r++){
			for(int c=1;c<=C;c++){
				cin>>m[r][c];
			}
		}
		for(int r=1;r<=R;r++){
			for(int c=1;c<=C;c++){
				m[r][c] += max(m[r-1][c],m[r][c-1]);
			}
		}
		cout<<m[R][C]<<endl;
	}
	return 0;
}

1211蚂蚁感冒

首先可以把他那个倒转方向的操作,看做相互穿过
假如蚂蚁0往右走,那他右边的往左走的蚂蚁肯定会感冒,接着他左边的向右走的也会感冒
但是如果他右边没有往左走的,那他左边往右走的不会感冒
所以要特判一下
蚂蚁0往左走同理

#include<iostream>
using namespace std;
const int maxx = 60;
int a[maxx];
int main(){
	int N;
	cin>>N;
	cin>>a[0];
	//左右两边朝着第一只蚂蚁走的个数
	int left=0,right=0;
	for(int i=1;i<N;i++){
		cin>>a[i];
		//朝着第一只蚂蚁走的都可能会被干扰
		if(a[i]>0&&(abs(a[i])<abs(a[0]))){
			left++;
		}else if(a[i]<0&&(abs(a[i])>abs(a[0]))){
			right++;
		}
	}
	int ans = left+right+1;
	//左边没有朝着蚂蚁0且蚂蚁0往左走
	if(left==0 && a[0]<0){
		ans=1;
	}
	//右边没有朝着蚂蚁0且蚂蚁0往右走
	if(right==0 && a[0]>0){
		ans=1;
	}
	cout<<ans<<endl;
	return 0;
}

1216 饮料换购

#include<iostream>
using namespace std;

int main(){
	int a,b;
	int ans = 0;
	cin>>a;
	b=0;
	while(true){
		ans += a;
		b += a;
		a = b/3;
		b = b%3;
		if(a==0)break;
	}
	cout<<ans<<endl;
	return 0;
}

4867整除数

#include<iostream>
using namespace std;

typedef long long ll;

int main(){
	int n,k;
	cin>>n>>k;
	int m = n%k;
	if(m==0){
		cout<<n+k<<endl;
	}else{
		cout<<n+k-m<<endl;
	}
	return 0;
}

4867整除数

#include<iostream>
using namespace std;

typedef long long ll;

int main(){
	int n,k;
	cin>>n>>k;
	int m = n%k;
	if(m==0){
		cout<<n+k<<endl;
	}else{
		cout<<n+k-m<<endl;
	}
	return 0;
}

104货仓选址

取中位数,即左边和右边的货舱数量一致

#include<iostream>
#include<algorithm>
using namespace std;
const int maxx = 1e5+10;

int a[maxx];

int main(){
	int N;
	cin>>N;
	for(int i=1;i<=N;i++){
		cin>>a[i];
	}
	sort(a+1,a+N+1);
	int addr;
	if(N%2){
		addr = a[N/2+1];
	}else{
		addr = (a[N/2]+a[N/2+1])>>1;
	}
	int ans = 0;
	for(int i=1;i<=N;i++){
		ans += abs(a[i]-addr);
	}
	cout<<ans<<endl;
	return 0;
}

1219移动距离

为了方便取余运算,减少心智压力,将所有的数都减一,即
1 2 3 4 5 6变为0 1 2 3 4 5

#include<iostream>
#include<algorithm>
using namespace std;

void get(int m,int w,int& r,int& c){
	int tmpr = m/w;
	int tmpc = m%w;
	if(tmpr%2){
		tmpc = w-tmpc-1;
	}
	r = tmpr;
	c = tmpc;
}

int main(){
	int w,m,n;
	cin>>w>>m>>n;
	m--;
	n--;
	//计算m的行和列
	int mr,mc,nr,nc;
	get(m,w,mr,mc);
	get(n,w,nr,nc);
	int ans = abs(mr-nr)+abs(mc-nc);
	cout<<ans<<endl;
	return 0;
}

1055股票买卖

#include<iostream>
using namespace std;

const int maxx = 1e5+10;

int dp[maxx][2];
int a[maxx];
int main(){
	int N;
	cin>>N;
	//不让dp[1][0]使用后者作为最大值
	dp[0][1]=-100000;
	for(int i=1;i<=N;i++){
		cin>>a[i];
		dp[i][0]=max(dp[i-1][0],dp[i-1][1]+a[i]);
		dp[i][1]=max(dp[i-1][1],dp[i-1][0]-a[i]);
	}
	cout<<dp[N][0]<<endl;
	return 0;
}

1245特别数的和

简单枚举

#include<iostream>
using namespace std;

bool check(int i){
	bool res = false;
	while(i){
		int mod = i%10;
		if(mod==2||mod==9||mod==0||mod==1){
			res=true;
			break;
		}
		i/=10;
	}
	return res;	
}

int main(){
	int n;
	cin>>n;
	int sum=0;
	for(int i=1;i<=n;i++){
		if(check(i)){
			sum+=i;
		}
	}
	cout<<sum<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值