Base 2 + Centers +Poisonous Full-Course + Best Performances

base 2:

题意:

给你一个序列a0,a1,a2.....a63。让你求他所a0*2^0+a1*2^1+......+a63*2^63次方。

思路:

这题很好理解,就是一个转进制的基础问题,但是要注意一点,long long有一位是符号位,所以要用unsigned long long来储存。使用pow()函数的朋友,记得用unsigned long long接收一下,默认返回是double类型,太小了。

代码:是

#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#include<map>
#include<stack>
#include<set>
#include<queue>
using namespace std;
string s;
#define maxn 500020
#define ll long long
#define int unsigned long long
int dp[maxn][2];
int a[maxn];
multiset<int,greater<int>>c,b;
int cmp(int a, int b)
{
	return a > b;
}
void solve()
{
	int k=1;
	int ans=0,n;
	for (int i = 0; i <= 63; i++)
	{
		cin >> n;
		ans += n * k;
		k <<= 1;
	}
	cout << ans;
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	solve();
	return 0;
}

 Centers:

题意:

给你一个序列,长度为3*n。让你按照他们按中间数出现的先后排序,即按照第二个数出现的顺序排序。

思路:

第二次出现的时候,直接打印。

代码:

#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#include<map>
#include<stack>
#include<set>
#include<queue>
using namespace std;
string s;
#define maxn 500020
#define ll long long
#define int  long long
int dp[maxn][2];
int a[maxn];
multiset<int,greater<int>>c,b;
map<int, int>m;
int cmp(int a, int b)
{
	return a > b;
}
void solve()
{
	int n;
	cin >> n;
	int x;
	for (int i = 1; i <= 3*n; i++)
	{
		cin >> x;
		m[x]++;
		if (m[x] == 2)
			cout << x<<" ";
	}

}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	solve();
	return 0;
}

 Poisonous Full-Course

题意:

一共有两种食物,有毒的和解毒的,都有一定的美味值(饱食度),按给你的顺序,你可以选择吃或跳过,要求获得的美味值(饱食度?)最大(不能寄)。如果你现在没中毒,你吃了有毒的事物会中毒,吃解毒事物没事;如果你现在中毒了,吃有毒的就寄了,吃解毒的可以恢复到没中毒的状态。初始健康没中毒。

思路:

我一开始没想到dp,各种if+调试半小时没写出来。大佬用dp很快写出来了。首先每一道菜上场的时候,都有类问题,吃或者不吃,当时是否中毒。dp[maxn][2],二维中的1代表中毒,0代表解毒。代码有注释。

代码:

#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#include<map>
#include<stack>
#include<set>
#include<queue>
using namespace std;
string s;
#define maxn 500020
#define ll long long
#define int  long long
int dp[maxn][2];
int a[maxn];
multiset<int,greater<int>>c,b;
map<int, int>m;
//b中保存的是前k个最大的,c中是全部的(按顺序)
//至于a用来检索
int cmp(int a, int b)
{
	return a > b;
}
void solve()
{
	int n;
	cin >> n;
	int x,y;
	for (int i = 1; i <= n; i++)
	{
		cin >> x >> y;
		if (x == 1)//当前事物有毒
		{
			//没中毒
			dp[i][0] = dp[i - 1][0];
			//中毒了可能是下列情况转化来的
			dp[i][1] = max(dp[i - 1][1],dp[i - 1][0] + y);
		}
		if (x == 0)//当前食物没毒
		{
			//中毒了,没吃
			dp[i][1] = dp[i - 1][1];
			//没中毒,可能没吃这个,可能是中毒了吃这个,没中毒吃这个。
			dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][1] + y, dp[i - 1][0] + y));
		}
	}
	cout << max(dp[n][0], dp[n][1]) << endl;;
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	solve();
	return 0;
}

Best Perform:

题意:

一共n个数,q次查询,每一次查询,我们需要找到最大的前k个数,然后输出他们的和。k次查询也有讲究,每次查询输入x,y。x是下标,把下标为x的数改成y,然后重新计算和。

思路:

我想的是开3个数组做,每次都sort排序一下,后来看大佬用的multiset,确实好用,我就用这个做了。中保存的是前k个最大的,c中是剩下n-k的个按顺序。具体看代码

代码:

#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#include<map>
#include<stack>
#include<set>
#include<queue>
using namespace std;
string s;
#define maxn 500020
#define ll long long
#define int long long
int dp[maxn][2];
int a[maxn];
multiset<int, greater<int>> b,c;
//b中保存的是前k个最大的,c中是剩下n-k的个按顺序
// 有人可能会问c有啥用,举个例子。五个数 5 4 3 2 1,k=4,sum=14
// 现在我把第一个数5改成0,理论上和为10(4+3+2+1),没这个列表无法实现这个功能
//至于a用来检索
int cmp(int a, int b)
{
	return a > b;
}
void solve()
{
	int n, k, q;

	cin >> n >> k >> q;
	int ans = 0;
	int x, y;
	for (int i = 1; i <= q; i++)
	{
		cin >> x >> y;
		//这个数在前k个中,因为不知道改大改小,所以先删掉。
		if (b.size() && b.find(a[x]) != b.end())
		{
			b.erase(b.find(a[x]));
			ans -= a[x];
		}
		//在另外
		else if(c.size()&& c.find(a[x]) != c.end())
			c.erase(c.find(a[x]));
		//删完直接插进c,然后和b中最小的比较。
		c.insert(y);
		a[x] = y;
		//不满的时候
		while (b.size() < k && c.size())
		{
			b.insert(*c.begin());
			ans += *c.begin();
			c.erase(c.begin());
		}
		//满了但是新来的大
		while (c.size() && *b.rbegin() < *c.begin())
		{
			ans -= *b.rbegin();
			ans += *c.begin();
			b.insert(*c.begin());
			c.insert(*b.rbegin());
			b.erase(b.find(*b.rbegin()));
			c.erase(c.find(*c.begin()));
		}
		cout << ans << endl;
	}
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	solve();
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值