假期一本通题目
二叉树数量
神奇算法彰显人类智慧(并不
通过一通乱搞地根据已有数据分析(其实是看数据找规律)我们不难发现(?)
当出现形似\(ab\)与\(ba\)这种逆序的一对的情况下,会导致最后的答案数乘上\(2\)(为什么会这样,小编也觉得很奇怪(并不))
所以根本不需要\(dfs\),我们出现了了一个神奇的算法和神奇的复杂度,也就是对于每一个对,都用\(find\)函数去找有没有逆序的这个对,如果有答案就乘上\(2\)
而这个算法具体成立地原因是如果满足这种情况的话就会产生一个单叶子节点,因为前序是中左右,后序时左右中,无法判断一个单叶子节点再左或右,因此也就只有这一种可能会产生两种情况
/*
* @Author: 2019yyy
* @Date: 2023-08-02 18:21:56
* @LastEditors: 2019yyy
* @LastEditTime: 2023-08-02 18:25:22
* @FilePath: \code\codeBiulders\T3407.cpp
* @Description:
*
* I love Chtholly forever
*/
#include<bits/stdc++.h>
using namespace std;
int main(){
int ans=1;
string a,b;
cin>>a>>b;
for(int i=0;i<a.length()-1;i++){
string str="";
str=str+a[i+1]+a[i];
int k=b.find(str);
if(k>=0){
ans=ans*2;
}
}
cout<<ans<<'\n';
return 0;
}
关于这个算法的时间复杂度,因为我不知道\(find\)函数的具体实现,所以优质回答,我不知道
但假设\(find\)是\(kmp\)实现的话就是\(O(len^2+2len)\)
货仓选址
先说结论,中位数的选址是最优的
若左侧\(x\)家商店,右侧\(y\)家,若\(x<y\)右移一定会让距离变小\(y-x\),\(x>y\)情况同理
#include<bits/stdc++.h>
using namespace std;
long long x[1100000],y[1100000],ans;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>x[i];//>>y[i];
}
sort(x+1,x+n+1);
int tx,ty;
for(int i=1;i<=n;i++){
ans=ans+abs(tx-x[i]);//+abs(ty-y[i]);
}
cout<<ans<<endl;
}
增减序列
从区间修改想到应该是差分数组
构建出差分数组后,题目转化为把差分数组所有元素变0
因为我们每次修改差分数组都是一个加一个减,所以我们希望每次修改都是加负的减正的,一对一对减,对于单个的再单独加减
所以问题一的答案就是\(max(正的差分值的和,负的差分值的和的相反数)\)
接下来是序列个数,前面一个加一个减的策略一定是最优的,不会产生多个解,那么唯一有可能产生多个解的就是单个加减的操作
对于单独的差分序列的修改,我们可以选取第一个值和这个单独的值,或者是最后一个值和这个单独的值也就产生了两种情况,这种单独的值一共有正的差分值的和加上负的差分值的和再加上1个
所以问题二的答案就是\(正的差分值的和+负的差分值的和+1\)
/*
* @Author: 2019yyy
* @Date: 2023-08-01 09:58:11
* @LastEditors: 2019yyy
* @LastEditTime: 2023-08-01 10:00:31
* @FilePath: \code\codeBiulders\T3933.cpp
* @Description:
*
* I love Chtholly forever
*/
#include<bits/stdc++.h>
using namespace std;
long long a[1100000];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
long long x=0,y=0;
for(int i=2;i<=n;i++){
if(a[i]-a[i-1]<0){
x=x+a[i-1]-a[i];
}else{
y=y+a[i]-a[i-1];
}
}
cout<<max(x,y)<<'\n'<<abs(x-y)+1<<'\n';
return 0;
}
电影
离散化,这里我用的\(map\)
/*
* @Author: 2019yyy
* @Date: 2023-08-01 15:16:51
* @LastEditors: 2019yyy
* @LastEditTime: 2023-08-01 15:31:41
* @FilePath: \code\codeBiulders\T1309.cpp
* @Description:
*
* I love Chtholly forever
*/
#include<bits/stdc++.h>
using namespace std;
map<int,int>m;
int a[2100000];
pair<int,int> q[2100000];
int main(){
int n,k;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
m[a[i]]++;
}
cin>>k;
for(int i=1;i<=k;i++){
cin>>q[i].first;
}
for(int i=1;i<=k;i++){
cin>>q[i].second;
}
int maxx=-0x3f3f3f3f;
for(int i=1;i<=k;i++){
maxx=max(maxx,m[q[i].first]);
}
int temp=-0x3f3f3f3f,ans;
for(int i=1;i<=k;i++){
if((m[q[i].first]==maxx)&&(temp<m[q[i].second])){
temp=m[q[i].second];
ans=i;
}
}
cout<<ans;
return 0;
}
最佳牛围栏
考虑使用二分把最值问题转化为可行性问题
二分平均值后给数组内每一个元素都减去\(mid\)
如果由前缀和大于\(0\)的情况,那么这个平均值就是可行的
/*
* @Author: 2019yyy
* @Date: 2023-08-01 10:12:15
* @LastEditors: 2019yyy
* @LastEditTime: 2023-08-01 10:31:02
* @FilePath: \code\codeBiulders\T1308.cpp
* @Description:
*
* I love Chtholly forever
*/
#include<bits/stdc++.h>
using namespace std;
int a[1100000];
double sum[1100000];
int n,k;
bool check(double x){
for(int i=1;i<=n;i++){
sum[i]=sum[i-1]+a[i]-x;
}
double minn=0x3f3f3f3f;
for(int i=1;i<=n-k+1;i++){
int t=i+k-1;
minn=min(minn,sum[i-1]);
if(sum[t]-minn>=0){
return true;
}
}
return false;
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
}
double l=0,r=2001,mid=0;
while(l+0.0001<=r){
mid=(l+r)/2;
if(check(mid)){
l=mid;
}else{
r=mid;
}
}
cout<<(int)(r*1000)<<'\n';
return 0;
}

浙公网安备 33010602011771号