20171020测试


得分:100 + 55 + 80

T1 刮刮卡(rock)

题意:一张卡花费 Ai元 获得 Bi元现金 和Bi积分 可先拿现金再支付花费
只能顺序刮卡 但可以把 前 k张卡顺次移动到最后 当有亏损时 结束刮卡
Ai总和 与Bi总和 相等

样例数据

输入




4 6 2 8 4 
1 5 7 9 2

输出

4
因为 Ai总和 与Bi总和 相等 所以总能从一个位置开始刮完所有的卡
贪心就好 每次为负的时候 从当前位置的下一位开始
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int k,n,a[2000005],b[2000005];
int read(){
	int i=0,f=1;char ch=getchar();
	for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') f=-1;
	for(;ch<='9'&&ch>='0';ch=getchar()) i=(i<<3)+(i<<1)+ch-'0';
	return i*f;
}
int main(){
	//freopen("rock.in","r",stdin);
	//freopen("rock.out","w",stdout);
	n=read();
	for(int i=1;i<=n;++i) b[i+n]=b[i]=read();
	for(int i=1;i<=n;++i) a[i+n]=a[i]=b[i]-read();
	int s=0,s1=0,s2=0;k=0;
	for(int i=1;i<=n*2-1;++i){
		s1+=b[i];s2+=a[i];s++;
		if(s2<0){
			s=0,s1=0,s2=0;
			k=i;
		}
		if(s==n) break;
	}
	cout<<k<<endl;
}
T2 矩阵(matrix)
题意:给出一个N*M的矩阵 去 k个子矩阵 输出子矩阵最大之和

样例数据

输入



3 2 2 
1 -3 
2 3 
-2 3

输出

9
1<=N<=100,1<=M<=2, 1<=k<=10
 DP ,粘个大佬的代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int read(){
	int i=0,f=1;char ch=getchar();
	for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') f=-1;
	for(;ch<='9'&&ch>='0';ch=getchar()) i=(i<<3)+(i<<1)+ch-'0';
	return i*f;
}
int buf[1024];
inline void write(int x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x) buf[++buf[0]]=x%10,x/=10;
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
#define stan 111
int n,m,k,amte[stan][stan],ansi,f[stan][stan][stan],a[stan];
signed main(){
	n=read();m=read();k=read();
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j)
			amte[i][j]=read();
	memset(f,-10,sizeof(f));
	if(m==1){
		for(int i=1;i<=n;++i)
			amte[i][1]+=amte[i-1][1];
		for(int i=0;i<=n;++i) 
			f[i][0][0]=0;
		for(int i=1;i<=n;++i)
			for(int j=1;j<=k;++j){
				f[i][j][0]=f[i-1][j][0];
				for(int t=0;t<i;++t)
					f[i][j][0]=max(f[i][j][0],f[t][j-1][0]+amte[i][1]-amte[t][1]);
			}
		write(f[n][k][0]);
		return 0;
	}else{
		ansi=-999999999;
		f[0][0][0]=0;
		for(int i=1;i<=n;++i){
			f[i][0][0]=0;
			for(int j=1;j<=k;++j){
				f[i][j][0]=max(f[i-1][j][0],max(f[i-1][j][1],max(f[i-1][j][2],max(f[i-1][j][3],f[i-1][j][4]))));
				f[i][j][1]=amte[i][1]+max(f[i-1][j-1][0],max(f[i-1][j-1][1],max(f[i-1][j-1][2],max(f[i-1][j-1][3],f[i-1][j-1][4]))));
				f[i][j][1]=max(f[i][j][1],amte[i][1]+max(f[i-1][j][1],f[i-1][j][3]));
				f[i][j][2]=amte[i][2]+max(f[i-1][j-1][0],max(f[i-1][j-1][1],max(f[i-1][j-1][2],max(f[i-1][j-1][3],f[i-1][j-1][4]))));
				f[i][j][2]=max(f[i][j][2],amte[i][2]+max(f[i-1][j][2],f[i-1][j][3]));
				if(j>=2)f[i][j][3]=amte[i][1]+amte[i][2]+max(f[i-1][j-2][0],max(f[i-1][j-2][1],max(f[i-1][j-2][2],max(f[i-1][j-2][3],f[i-1][j-2][4]))));
				f[i][j][3]=max(f[i][j][3],amte[i][1]+amte[i][2]+max(max(f[i-1][j-1][1],f[i-1][j-1][2]),f[i-1][j-1][3]));
				f[i][j][3]=max(f[i][j][3],amte[i][1]+amte[i][2]+f[i-1][j][3]);
				f[i][j][4]=amte[i][1]+amte[i][2]+max(f[i-1][j-1][0],max(f[i-1][j-1][1],max(f[i-1][j-1][2],max(f[i-1][j-1][4],f[i-1][j-1][3]))));
				f[i][j][4]=max(f[i][j][4],amte[i][1]+amte[i][2]+f[i-1][j][4]);
			}
		}
		
		for(int i=1;i<=n;++i)
			for(int l=0;l<=4;++l)
				ansi=max(ansi,f[i][k][l]);
		write(ansi);
	}
	return 0;
}
T3 裁剪表格 (table)
题意:一个N*M的矩阵 q次操作 每次交换两个矩阵
每次操作 六个整数 r1,c1,r2,c2,h,w 表示第一个矩阵左上角所在行、所在列,第二个矩阵左上角所在行、所在列
两个矩阵的高度和宽度 

样例数据

输入



4 4 2 
1 1 2 2 
1 1 2 2 
3 3 4 4 
3 3 4 4 
1 1 3 3 2 2 
3 1 1 3 2 2

输出

4 4 3 3 
4 4 3 3 
2 2 1 1 
2 2 1 1
考试的时候 交的暴力 100分 ??? 一脸懵逼 改数据后 80分(我明明打的30分暴力好吧)
貌似 暴力加 register 可以过100
在OJ上提交的暴力也是100 OJ上开了 O2的原因
考试的时候可用 register 优化 达到手动开 O2的效果(其实比开 O2慢多了 但是比普通的快很多)
还有 好像 用 swap比 用 &来交换两个数要快唉
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,q,r1,r2,c1,c2,h,w;
int a[1005][1005];
int read(){
	int i=0,f=1;char ch=getchar();
	for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') f=-1;
	for(;ch<='9'&&ch>='0';ch=getchar()) i=(i<<3)+(i<<1)+ch-'0';
	return i*f;
}
int main(){
	//freopen("table.in","r",stdin);
	//freopen("table.out","w",stdout);
	n=read();m=read();q=read();
	int fl=1;
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j){
			a[i][j]=read();
			if(a[i][j]!=1) fl=0;
		}
	if(fl){
		for(int i=1;i<=n;++i){
			for(int j=1;j<=m;++j) cout<<"1"<<" ";
			cout<<endl;
		}
		return 0;
	}
	for(int i=1;i<=q;++i){
		r1=read(),c1=read(),r2=read(),c2=read();h=read();w=read();
		for(int j=0;j<h;++j)
			for(int k=0;k<w;++k){
				swap(a[r1+j][c1+k],a[r2+j][c2+k]);
			}
	}
	for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j) cout<<a[i][j]<<" ";
		cout<<endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值