本周学习总结22.6.6-6.19:比赛、背包、DP

Problem - A - Codeforces 题意是构建一个基座,平台1高于平台2,平台2高于平台3,三者两两不能同高,并且还要让平台1尽可能的低(但不低于平台2),给出高度的总和,求平台2,1,3的高度(必须是整数),这个我本来是直接用暴力枚举,用三个循环来筛结果,就是当a+b+c=n并且a>b&&b>c&&a>c时分别输出b,a,c,由于它给出的数最大为10^5,三个for就会超时,第一次便Time limit exceeded on test 1了,然后和同学讨论了一下

#include<iostream>
using namespace std;
int main()
{
	int n;
	long long a;
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> a;
		long long j = a / 3;
		if (j * 3 + 2 == a) {
			cout << j + 1 << " " << j + 2 << " " << j - 1 << endl;
		}
		else if (j * 3 + 1 == a)
			cout << j << " " << j + 2 << " " << j - 1 << endl;
		else cout << j << " " << j + 1 << " " << j - 1 << endl;

	}
}

问题 - B - 代码部队 (codeforces.com) 操作修改数组的题,题意是给出两段非负整数的数组,每次操作会把第一段数组的所有数据-1,如果某数据等于0之后将不做修改,求在n次修改之后能否使得第一段数组等于第二段数组。我的思路是,首先判断两段数组中有没有第二段比第一段大的数据,如果有直接输出“NO”,否则继续判断,以其中最大的值作为循环的次数,每次循环都-1,在此之中若两数组相等停止循环输出“YES”,循环结束仍未相等输出“NO”。

#include<iostream>
using namespace std;
int t, a[50000], b[50000], c[50000] = { 0 };
int main() {
	cin >> t;
	for (int u = 1; u <= t; u++) {
		int n;
		int index = 0;
		cin >> n;
		for (int i = 1; i <= n; i++) {
			cin >> a[i];
		}
		for (int i = 1; i <= n; i++) {
			cin >> b[i];
		}
		if (n == 1) {
			if (a[1] < b[1]) {
				cout << "NO" << endl;
				goto fuck;
				break;
			}
			else {
				cout << "YES" << endl; goto fuck;
				break;
			}
		}
		for (int i = 1; i <= n; i++) {
			if (a[i] < b[i]&&a[i]!=0) {
				cout << "NO" << endl; goto fuck;
				break;
			}
			if (a[i] > b[i] && b[i] != 0) {
				c[index] = a[i] - b[i];
				index++;
			}
		}
		for (int i = 0; i < index-1; i++) {
			for (int j = i; j < index - 1; j++) {
                if (c[i] != c[j]) {
				    cout <<"NO" << endl; goto fuck;
				    index = 0;
				    break;
			}
			}
			
		}
		cout << "YES" << endl;
		fuck:
		index = 0;
	}
}

代码我是实现出来了,但是就是Wrong answer on test 2,给出的测试点是能够通过的,test 2不能通过,最后我这个题还是卡在2没过。

Problem - A - Codeforces 给出四段数据,求第二到第四段中比第一段数据大的数量,签到题,总共用了16分钟,其中15分钟在加载页面。

#include<iostream>
using namespace std;
int main() {
	int t,a,b,c,d;
	cin >> t;
	for (int i = 1; i <= t; i++) {
		cin >> a >> b >> c >> d;
		int n = 0;
		if (a < b)n++;
		if (a < c)n++;
		if (a < d)n++;
		cout << n << endl;
	}
}

 Problem - C - Codeforces 二维数组的题,就是两对角线求相交之处的坐标,div4的c题比div3的签到题还简单,一下子就ac出来了。思路就是,遍历各个坐标,当该坐标和该坐标的左上左下右上右下都是#时输出坐标即可。

#include<iostream>
using namespace std;
int main() {
	int t;
	char a[20][20];
	cin >> t;
	for (int o = 1; o <= t; o++) {
		
		for (int i = 1; i <= 8; i++) {
			for (int j = 1; j <= 8; j++) {
				char b;
				cin >> b;
				a[i][j] = b;
			}
		}
		//cout << 12345 << endl;
		for (int i = 1; i <= 8; i++) {
			for (int j = 1; j <= 8; j++) {
				if(a[i][j]=='#'&&a[i-1][j-1]=='#'&&a[i+1][j+1]=='#'&&a[i-1][j+1]=='#'&&a[i+1][j-1]=='#') {
					cout << i << " " << j << endl;
					break;
				}
			}
		}
	}
}

本周主要是打比赛和把背包的题看了看做了一下,01背包一直自己实现不出来,每次都是递归的关系式弄不清楚,上个月看动态规划的博客的时候正好看到了背包有关的例题,当时自己也尝试做了几道,反正就是不看题解是ac不出来。

 P1507 NASA的食物计划 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

 一个找最优背包的题,题意是给出了最大存储空间和最大存储质量,以及需要载的物品,求在不超过最大储存空间的最大存储质量的前提下存储最大卡路里,这个找最优解的题应该是背包题中最简单的一道题之一,开一个二维数组存储,然后直接就可以套用01背包中f[j]=max{f[j],f[j-a[i]]+c[i],然后因为有两个关键变量所以设一个二维数组f[j][l],然后f[l]也可以直接套用上面那个公式,只要稍微变动一下就行了。

#include<iostream>
using namespace std;
int a[51],b[51],c[51];
int f[501][501];
int main()
{
    int i,j,l,m,n,k;
    cin>>m>>n>>k;
    for(i=1;i<=k;i++)
        cin>>a[i]>>b[i]>>c[i];
    for(i=1;i<=n;i++)
        for(j=m;j>=a[i];j--)
          for(l=n;l>=b[i];l--)
            f[j][l]=max(f[j][l],f[j-a[i]][l-b[i]]+c[i]);
      cout<<f[m][n]<<endl;
      return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_61789994/article/details/125292208