CF第633场 (Div. 2)
今天开始也开始写cf题解了,致力于分析巧解和题目的思维。
本次战绩:惨不忍睹,一直卡D,看来必须要进行数据结构了,说的也是,dfs和bfs都不会写是真的丢人。
A题Filling Diamonds
可能很多人是输入n输出n
简单提一下为什么是n种,因为每一种的区别在竖着的位于哪一块。
比如n=4的时候:
你可能已经发现了,所以是这个样子:
B题Sorted Adjacent Differences
题意就是排完序后是数组的前后差值越来越大,于是可以这个样子
怎么确定对呢?
对于一个最大值,与它差值最大是最小值
然后一旦没了最大值,次大值就与最小值相差最大了
(我居然边敲边怀疑,真是一打比赛脑子就不行)
然后就直接使用algorithm里面的sort,找个左下标和右下标往中间靠
#include<iostream>
#include<algorithm>
using namespace std;
int q[100007];
int an[100007];
int main(){
int t;
cin >> t;
while (t--){
int n;
scanf("%d", &n);
int l = 0, r = n - 1;
for (int i = 0; i < n; i++)
scanf("%d", &q[i]);
sort(q, q + n);
for (int i = n-1; i >=0; i--){
if (i & 1)
an[i] = q[l++];
else
an[i] = q[r--];
}
for (int i = 0; i < n; i++)
printf("%d%c", an[i],i==n-1?'\n':' ');
}
return 0;
}
C题Powered Addition
其实就是给你一个数组,让你把这个数组变成一个非严格递增数组,比如1,1,2什么的。
然后第一次可以给数组中一些元素加1,第二次可以加2,第三次可以加4,第四次可以加8…第n次可以加2^(n-1)。
当时一想觉得非常麻烦,如果先变后边,到时候前边一变就比会后大了,后边还得变什么balabala什么的,后来我突然一拍脑门。
不对啊,这不是二进制么?二进制可以组成任何数
然后就发现,当加的值最少时。一定会出现这种情况:
很显然了,就是所有数都要补到跟左边已有的最大,那么只要统计出所有max(左边最大值-当前值)就可以了。
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &q[i]);
int an = 0;
int ans = -1e9;
for (int i = 0; i < n; i++){
ans = max(q[i], ans);
if (q[i] < ans)
an = max(an, ans - q[i]);
}
当然这算出来的是必须准备的差值,再二进制稍稍处理一下就可以了。
int s(int x){
int in = 0;
while (x){
in++;
x /= 2;
}
return in;
}
D题Edge Weight Assignment
关于大致的题解官方写的更好,最小值的处理我有这样的思想。
从度最高的节点进行BFS没错,就是广搜,遇到叶子结点统计深度,然后计算奇偶。
这样所有节点只需便利一次即可判断。
关于广搜的统计深度,我使用的是用-1作为层数结束标记。
于是乎:
bool ff[100007];//用于检测这个点有没有被访问过
void bfs(int x,int &j,int &o){
queue<int> qu;//队列
qu.push(x);//把度最高的点压进去
ff[x] = 1;//这个点被访问过了
int an = 1;//就是一个判断奇数偶数的,我也不知道一开始奇数还是偶数,但是如果同时出现奇偶就不是1
qu.push(-1);//一层的标记,如果遇到-1就会取反
while (qu.size()!=1){
int top = qu.front();//取队头
qu.pop();//取完立马丢掉
if (top != -1){//当不是标记时,进行常规操作
for (int i = 0; i < q[top].size(); i++)
if (q[q[top][i]].size() == 1)//是叶子节点
if (an) j++;
else o++;
else if (!ff[q[top][i]])//压入该点,并标记访问(前提没有被访问过)
qu.push(q[top][i]),ff[q[top][i]] = 1;
}
if (qu.front() == -1){//遍历一层,进行奇偶取反,并尾部再次压入-1标记层数
qu.push(-1);
an ^= 1;
qu.pop();
}
}
}
代码写的确实很乱,但是我还是加了详细的注解。
不要为我为什么不写DFS,我发现我不会QWQ。(写了1个半小时的DFS还是错的)
E题(还不会)
目前还不会,但确实发现了是这样的:
1 2 3
4 8 12
5 10 15
6 11 13
7 9 14
本次教训:人至少得会DFS,至少不能不会写树的遍历
数据结构必须得学 QWQ