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题,太难不做了。