VPVPVPVPVP+刷题刷题刷题

每天最快乐的事除了刷题就是VP

//------ 棘手大学 世界第一 ------//

C - Popcorn (atcoder.jp)

刚开始想了一下没想出来,一看我靠,数据范围这么小dfs就能过

我们给定一个初始化全是x的字符串s(自己取最大数据范围就行了,反正也才两位数),从1号摊位开始搜索,若过摊位对应的位置为o,那么我们把s的对应位置也变成o,每次对一个摊位遍历完我们可以有两种选择(1、选择当前摊位并把答案+1继续搜索,2、不选择当前摊位答案不变继续搜索)

AC代码:

//吉大出品 必出精品
string str[11];
int n, m, ans = 1e9;
void dfs(int x, int num, string s)
{
	if (x >= n)return;
	bool flag = true;
	string ss = s;
	for (int i = 0; i < m; i++)
	{
		if (str[x][i] == 'o')s[i] = 'o';
		if (s[i] == 'x')flag = false;
	}
	if (flag)ans = min(ans, num + 1);
	else
		dfs(x + 1, num + 1, s);
	dfs(x + 1, num, ss);
	return;
}
void solve()
{
	cin >> n >> m;
	for (int i = 0; i < n; i++)
	{
		cin >> str[i];
	}
	dfs(0, 0, "xxxxxxxxxx");
	cout << ans << endl;
	return;
}

P2285 [HNOI2004] 打鼹鼠 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

很有意思的题目,线性dp,因为是按时间递增的,后面的对前面的进行遍历,只要时间差>=坐标的差值之和我们就可以将其+1(本身就可以为1,因为机器人可以直接放到任一点),对于每个点往前进行遍历得到可能的最大num值,最后将最大值输出即可

struct node
{
	ll t, x, y, num = 1;
};
node a[N];
void solve()
{
	ll n, m;
	cin >> n >> m;
	for (int i = 0; i < m; i++)
	{
		cin >> a[i].t >> a[i].x >> a[i].y;
	}
	ll ans = 0, mx = 0;
	for (int i = 0; i < m; i++)
	{
		mx = 0;
		for (int j = 0; j < i; j++)
		{
			if (a[i].t - a[j].t >= abs(a[i].x - a[j].x) + abs(a[i].y - a[j].y))
			{
				mx = max(mx, a[j].num);
			}
		}
		a[i].num += mx;
		ans = max(ans, a[i].num);
	}
	cout << ans << endl;
	return;
}

C - Minimum Glutton (atcoder.jp)

将两个数组分别从大到小进行排列,分别计算其最小数,再将两数进行比较得到最小值即可

ll a[N], b[N];
bool qq(ll q, ll w)
{
	return q > w;
}
void solve()
{
	ll n, x, y;
	cin >> n >> x >> y;
	for (int i = 1; i <= n; i++)
		cin >> a[i];
	for (int i = 1; i <= n; i++)
		cin >> b[i];
	ll ans1 = 0, ans2 = 0;
	sort(a + 1, a + 1 + n, qq);
	sort(b + 1, b + 1 + n, qq);
	ll sum1 = 0, sum2 = 0;
	for (int i = 1; i <= n; i++)
	{
		sum1 += a[i];
		ans1++;
		if (sum1 > x)break;
	}
	for (int i = 1; i <= n; i++)
	{
		sum2 += b[i];
		ans2++;
		if (sum2 > y)break;
	}
	ll ans = min(ans1, ans2);
	cout << ans << endl;
	return;
}

Problem - B - Codeforces

只要涉及位运算的就有点摸不着头脑 ,想了半天没一点头绪只能跑去看题解

将x转化为二进制从最开始一直到题目要求的最大位数进行遍历,用一个数组来记录(只能为1,0,-1),若转化的当前位数值>1则将数组的下一位值定为1,当前数组位的值为0(我们此时的目的之一也是慢慢记录x的范围然后一步步缩小直到确定),若不>1则需要分情况讨论(第一种是前一位>1是需要再进一位,即后一位为1,前一位为-1),若不等于1即将当前位为1即可

题解代码:

void solve()
{
	ll x;
	cin >> x;
	vector<int>a(31, 0);
	for (int i = 0; i < 30; i++)
	{
		if (1ll & (x >> i))
		{
			a[i + 1] = 1;
			a[i] = 0;
		}
		else if (i > 0)
		{
			if (a[i - 1] == 1)
			{
				a[i + 1] = 1;
				a[i - 1] = -1;
			}
			else
			{
				a[i] = 1;
			}
		}
		else if (i == 0)
		{
			a[i] = 1;
		}
	}
	cout << "31\n";
	for (int i = 0; i < 31; i++)
	{
		cout << a[i] << " ";
	}
	cout << "\n";
	return;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值