Codeforces Round #366 (Div. 2)

这套div2的题感觉难度比较低

A:

水题

B:

博弈论,但是很简单。最终必须把所有的数分解为1,所以只有考虑每个数要分解a[i]-1次,每次sum累加模2进行判断即可

C:

这题是div2的C题但是div1的A题,一不小心做了div1去了。

题意:

手机的app有通知,现在有n个app,q个操作。一共有3种操作:1.appX产生一个通知;2.阅读appX的所有通知;3.阅读前t条通知(其中有的通知可能已经读过)。

要点:

就是一个队列模拟,具体解析看下面的代码吧。

#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int N = 300005;
struct node
{
	int time, pos;//记录时间和对应app
};
queue<node> que;
queue<int> Q[N];//存储每个app对应的所有通知产生的时间
bool vis[N];//存储产生于t时间的通知是否已经被读过

int main()
{
	int n, q,order,num;
	scanf("%d%d", &n, &q);
	memset(vis, false, sizeof(vis));
	int ans = 0,ant=1;//ant作为通知产生时间
	while(q--)
	{
		scanf("%d%d", &order, &num);
		if (order == 1)
		{
			node temp;
			temp.time = ant;
			temp.pos = num;
			que.push(temp);
			Q[num].push(ant);
			ans++;
			ant++;
		}
		else if(order==2)
		{
			while (!Q[num].empty())
			{
				int u = Q[num].front(); Q[num].pop();
				vis[u] = true;
				ans--;
			}
		}
		else
		{
			while (!que.empty()&&que.front().time<=num)
			{
				node u = que.front();que.pop();
				if (!vis[u.time])
				{
					Q[u.pos].pop();
					vis[u.time] = true;
					ans--;
				}
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}

D:

这题一开始觉得是dp,后来发现不行。看了一下题解是一道比较巧妙的贪心,将起点和终点连成一条链,贪心的过程就是在链的不同点之间插入,选择最小的那个点。程序还是比较好写的。

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 5005;
int net[N];
long long x[N], a[N], b[N], c[N], d[N];

long long add(int i, int j)//从i移动到j
{
	if (i > j)
		return abs(x[i] - x[j]) + c[i] + b[j];
	else
		return abs(x[i] - x[j]) + d[i] + a[j];
}

int main()
{
	int n, s, e,i,j,k;
	scanf("%d%d%d", &n, &s, &e);
	for (i = 1; i <= n; i++)
		scanf("%I64d", &x[i]);
	for (i = 1; i <= n; i++)
		scanf("%I64d", &a[i]);
	for (i = 1; i <= n; i++)
		scanf("%I64d", &b[i]);
	for (i = 1; i <= n; i++)
		scanf("%I64d", &c[i]);
	for (i = 1; i <= n; i++)
		scanf("%I64d", &d[i]);
	long long sum = 0;
	net[s] = e;
	sum += add(s, e);
	for (i = 1; i <= n; i++)
	{
		if (i == s || i == e)
			continue;
		int best;
		long long k = 10000000000000ll;
		for (j = s; j !=e; j=net[j])//贪心,往链中插入
		{
			long long temp = add(j, i) + add(i, net[j]) - add(j, net[j]);
			if (temp < k)
			{
				k = temp;
				best = j;
			}
		}
		sum += k;
		net[i] = net[best];
		net[best] = i;
	}
	printf("%I64d\n", sum);
	return 0;
}

E:

dp题,太难不做了。




posted @ 2016-09-30 09:56  seasonal  阅读(78)  评论(0编辑  收藏  举报