题目地址:http://oj.saikr.com/contest
文章目录
前言
本人的话,对于算法不太会,这次也只ac了3题,记下来用于自己使用
一、B题 ERROR?
1.题目
2.思路
因为题目要求最小的eps,我们稍微分析一下题目就可以发现只要当前搜索到的eps满足条件,
更大的eps肯定也满足该条件,所以我们可以考虑二分来搜索最小的eps;
然后b(i)的两个边界值为a(i)+eps和a(i)-eps;
我们可以让前面的b(i)全部通过贪心搜索成最小的,
例如先把b(1)=a(1)-eps,但这里要注意的是b是正整数序列,
所以这里如果b(1)<0的话,就得让b(1)=1;
剩下的序列的话,最好能让b(i)只比b(i-1)大1,
如果不能的话,让b(i)=a(i)-eps试试
3.代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define int long long
const int N=2e6+10;
int n,a[N],b[N];
bool check(int eps){
for(int i=1;i<=n;i++) b[i]=a[i];
b[1]-=eps;
b[1]=max(b[1],1LL);
for(int i=2;i<=n;i++){
if(b[i]+eps<=b[i-1]) return false;
if(b[i]-eps>b[i-1])
b[i]-=eps;
else{
if(b[i]+eps>b[i-1])
b[i]=b[i-1]+1;
else return false;
}
}
return true;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int left=0,right=1e9+10;
while(left<right){
int mid=(left+right)>>1LL;
if(check(mid)){
right=mid;
}else{
left=mid+1;
}
}
cout<<right;
return 0;
}
二、E题 吃利息
1.题目
2.思路
简单模拟题
3.代码
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++){
int li_xi=n/10;
if(li_xi>5){
n+=10;
}else{
n+=(li_xi+5);
}
}
cout<<n<<endl;
return 0;
}
三、G题 MP4
1.题目
2.思路
比赛时候的思路:
打算直接直接定义一个sort比较的cmp仿函数,但明显复杂度过高,TLE了,
后来想的思路:
因为只用找字典序前五十个最小的,所以我们可以直接用dfs跳跃搜索,
定义dfs(left,right,num)的搜索函数,
即在[left,right]中搜索,具体注释看代码
3.代码
#include<bits/stdc++.h>
using namespace std;
#define IOS \
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define ll long long
#define int long long
int sum,n;
//搜索[l,r]内的k个数
void dfs(int l,int r,int k){
if(r>n) r=n;//调整数据范围
for(int i=l;i<=r;i++){
//这里因为dfs每次向下搜索都是扩大十倍搜索的,所以当如果当前被搜索的这个
//的数不是左边界且能被10整除,说明该数前还有更小的数能够被搜索到
if(i!=l&&i%10==0)
return ;
sum++;
if(sum<=k){
cout<<i<<".mp4"<<endl;
if(sum==k)//搜索到想要搜索到的个数
return ;
}
if(i*10<=n){
dfs(i*10,i*100-1,k);
}
}
}
signed main(){
IOS //解绑加快输入输出速度
cin>>n;
dfs(1,9,50);
return 0;
}
/*超时代码*/
四、I题 展览
1.题目
2.思路
现在的话还是没有思路,因为自己一开始想的是递归求最大值,
就是下步选与不选该值异或,具体看代码
但是不知道怎么剪枝降低复杂度,TLE了,自己好菜qaq
3.代码
/*超时代码,正确代码待加*/
#include<bits/stdc++.h>
using namespace std;
int ans=0,n;
int a[50];
void dfs(int val,int k){
if(k==n+1){
ans=max(ans,val);
return ;
}
dfs(val,k+1);//下一步数不选
dfs(val ^ a[k],k+1); //下一步选
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
dfs(0,0);
cout<<ans<<endl;
return 0;
}
五、I题 礼物
1.题目
2.代码
#include<bits/stdc++.h>
using namespace std;
bool cmp_max(int x,int y){
return x > y;
}
int main(){
int n,m;
cin>>n;
vector<int> vec;
for(int i=0;i<n;i++){
cin>>m;
vec.push_back(m);
}
sort(vec.begin(),vec.end(),cmp_max);
cout<<vec.front()<<endl;
return 0;
}
总结
总的来说,虽然这次自己只AC了3.5道题目,但相比上一次只做了个签到题,还是有进步的,虽然依旧很菜,哈哈哈,继续努力,剩下的题目自己再学会再加上,算法虐我千百遍,我待算法如初恋(不是)。