2021牛客暑期多校训练营10
最后一次牛客,看到是cjb命题觉得应该是那种做起来很爽的题吧,毕竟打过很多次他命题的比赛都觉得体验非常好,结果两题罚坐到头……(没有说邦邦不好的意思(嗯)
这个暑假的现场赛结束了(没有参加今年杭电,在vp去年的),希望自己有所进步,有所收获。
(后期会看自己学习情况补其他题,先开个坑)
F-Train Wreck
思路
把栈操作转换为树上操作(队友的思路绝绝子),如果是push就是在当前节点上添加一个子节点(并将指针转移到子节点上),如果是pop就是将指针移动到当前节点的父亲节点,这样我们就能建出一颗 n + 1 n + 1 n+1 个点的树(之所以是 n + 1 n+1 n+1,是因为指针指空的时候安排一个0号节点,不然建出来是森林),父亲节点相同的节点之间存在冲突关系,不能是同一种颜色。
在安排颜色的时候,也需要按照该颜色的数量多的先安排的思路,否则样例就过不去。
代码
赛场上是队友写的,赛后完全自己独立写了一下,一遍过,好耶ヽ(✿゚▽゚)ノ
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 4e6 + 10;
const ll INF = 0x3f3f3f3f;
vector<int> es[N];
int par[N];
int num[N];
int co[N];
string str;
void addEdge(int u, int v)
{
es[u].push_back(v);
}
struct node
{
int col;
int num;
bool operator < (const node& obj) const
{
return num < obj.num;
}
};
priority_queue<node> que;
stack<int> st;
struct node2
{
int id;
int num;
bool operator < (const node2& obj) const
{
return num > obj.num;
}
};
vector<node2> vec;
int main()
{
int n;
int cnt = 1;
cin >> n;
cin >> str;
int fa = 0;
for(int i = 0; i < 2 * n; i++)
{
if(str[i] == ')')
fa = par[fa];
else
{
addEdge(fa, cnt);
par[cnt] = fa;
fa = cnt;
cnt++;
}
}
for(int i = 0; i <= n; i++)
{
if(es[i].size())
vec.push_back({i, (int)es[i].size()});
}
sort(vec.begin(), vec.end());
for(int i = 0, col; i < n; i++)
{
cin >> col;
if(!num[col])
st.push(col);
num[col]++;
}
while(!st.empty())
{
int col = st.top();
st.pop();
que.push({col, num[col]});
}
bool flag = 0;
for(auto fa : vec)
{
vector<node> tmp;
for(auto son : es[fa.id])
{
if(!que.size())
{
flag = 1;
break;
}
node now = que.top();
que.pop();
co[son] = now.col;
now.num--;
if(now.num)
tmp.push_back(now);
}
for(auto now : tmp)
{
que.push(now);
}
}
if(flag)
{
cout << "NO" << endl;
return 0;
}
cout << "YES" << endl;
for(int i = 1; i <= n; i++)
{
cout << co[i];
if(i != n)
cout << " " ;
}
cout << endl;
return 0;
}
H-War of Inazuma (Easy Version)
思路
当时实验室大部分人都过了,我们队还是想不出,,,然后我只能硬着头皮手模了一下,模出来这个:
于是才发现了其实1的个数为 i i i 的节点只会和个数为 i − 1 , i + 1 i - 1, \ i + 1 i−1, i+1 的节点相关,所以按照1的个数为奇数/偶数染不同颜色就可以了。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int cal(int num)
{
int cnt = 0;
while(num)
{
if(num & 1)
cnt++;
num >>= 1;
}
return cnt;
}
int main()
{
int n;
cin >> n;
for(int i = 0; i < (1 << n); i++)
{
if(cal(i) & 1)
{
cout << 0;
}
else
{
cout << 1;
}
}
cout << endl;
return 0;
}