20南京站补题(EF)+cf数学
Posted 钟钟终
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了20南京站补题(EF)+cf数学相关的知识,希望对你有一定的参考价值。
H. Gambling
自己的代码属实丑陋,虽然该注意到的点都想到了,但就是打不对。可能还是思路不够清晰,代码能力不过关。
思路:
1.刚开始的钱是1元。因此对于一个数来说,后面跟着的数在数量上不能超过该数字的有效数量(抵消的时候记录最大值)。
2.主要发生抵消后的数字大于等于1,那么就记录更新。过程中记录最大值和左右端点。
代码:
#include <bits/stdc++.h>
#define int long long
#define ios cin.tie(0),cout.tie(0),ios::sync_with_stdio(0);
#define endl '\\n'
#define ULL unsigned long long
using namespace std;
const double eps=1e-8;
const int mod=998244353;
const int N=1e6+5;
const int P=131;
int n,a[N];
unordered_map<int,pair<int,int>>mp;
unordered_map<int,int>val;
void solve()
mp.clear();
val.clear();
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
int mx=1,ans=a[1],l=1,r=1;
for(int i=1;i<=n;i++)
if(mp.count(a[i]))
int tmp=val[a[i]];
tmp=tmp-(i-mp[a[i]].second-1)+1;
//cout<<a[i]<<" "<<val[a[i]]<<" "<<tmp<<endl;
if(tmp<=0)
mp[a[i]]=i,i;val[a[i]]=1;
else
val[a[i]]=tmp;
mp[a[i]].second=i;
if(mx<val[a[i]])
mx=val[a[i]],ans=a[i],l=mp[a[i]].first,r=mp[a[i]].second;
else
mp[a[i]]=i,i;val[a[i]]=1;
cout<<ans<<" "<<l<<" "<<r<<endl;
signed main()
ios;
int T;cin>>T;
while(T--)
solve();
return 0;
// int ans=0,l=0,r=0,mx=0;
// for(int i=1;i<=n;i++)
//
// cin>>a[i];
// if(!mp[a[i]].size())
//
// mp[a[i]].push_back(i),val[a[i]]=1,mm[a[i]]=i,i;
// if(mx<val[a[i]])
// mx=val[a[i]],ans=a[i],l=mm[a[i]].first,r=mm[a[i]].second;
// continue;
//
// if(i-mp[a[i]].back()-1>=mp[a[i]].size())
//
// mp[a[i]].clear();mp[a[i]].push_back(i);
// val[a[i]]=1;mm[a[i]]=i,i;
//
// int p=mp[a[i]].back();
// mp[a[i]].push_back(i);
// if(mp[a[i]].size()-(i-p-1)>val[a[i]])
//
// val[a[i]]=mp[a[i]].size()-(i-p-1);
// mm[a[i]]=mp[a[i]].front(),i;
//
// if(mx<val[a[i]])
// mx=val[a[i]],ans=a[i],l=mm[a[i]].first,r=mm[a[i]].second;
//
// int g,mx=0;
// for(auto x:mp)
//
// int tmp=0;
// for(int i=0;i<x.second.size();i++) cout<<mp[x.first][i]<<" ";
// cout<<endl;
// for(int i=x.second.size()-1;i>=1;i--)
//
// tmp+=mp[x.first][i]-mp[x.first][i-1]-1;
//
// int p=mp[x.first].size();
// int q=mp[x.first].back()-mp[x.first].front()+1-p;
// //cout<<p<<" "<<q<<endl;
// p=p-q;
// //cout<<p<<endl;
// if(p>mx)
//
// mx=p;g=x.first;
//
//
F .Fireworks
学到的新技巧,三分板子。用于处理凹凸函数的极值问题,感觉跟模拟退火很像。
思路:
1.对于一批做好的火柴,都失败的概率为(1-p)k ,则成功的概率为1-(1-p)k
2.则1/1-(1-p)k 是期望的次数,每次的时间为n*k+m
3.得出公式:n * k+m/(1-(1-p)k)
4.判断函数为凹凸函数,两次求到后结果为常数.(对于一定为整数的分母,可选择性不看,分子进行二次求导可全约掉)
4.处理方法有三分和模拟退火。
#include <bits/stdc++.h>
#define int long long
#define ios cin.tie(0),cout.tie(0),ios::sync_with_stdio(0);
#define endl '\\n'
#define ULL unsigned long long
using namespace std;
const double eps=1e-8;
const double dinf=1e18;
const int mod=998244353;
const int P=131;
const int N=1e6+5;
double n,m,p,ans=dinf;
double fun(int x)
return (1.0*x*n+m)/(1-pow(1-p,x));
void solve()
cin>>n>>m>>p;
p*=1e-4;
int l=0,r=1e9;
while(l+5<=r)
int m1=(l+r)>>1;
int m2=(m1+r)>>1;
if(fun(m1)>fun(m2)) l=m1;
else r=m2;
ans=fun(l);
for(int i=l+1;i<=r;i++)
ans=min(ans,fun(i));
cout<<fixed<<setprecision(12)<<ans<<endl;
signed main()
ios;
int T;cin>>T;
while(T--)
solve();
return 0;
被卡掉的模拟退火做法:
#include <bits/stdc++.h>
#define int long long
#define ios cin.tie(0),cout.tie(0),ios::sync_with_stdio(0);
#define endl '\\n'
#define ULL unsigned long long
#define down 0.996
using namespace std;
const double eps=1e-8;
const double dinf=1e18;
const int mod=998244353;
const int P=131;
const int N=1e6+5;
double n,m,p,answ;
int ansx;
double fun(int x)
return (1.0*x*n+m)/(1-pow(1-p,x));
void sa()
double t=2000;
while(t>1e-12)
int ax=ansx+(rand()*2-RAND_MAX)*t; // [-32767,+32767]
if(ax<=0) continue;
double aw=fun(ax); //随机跳值的x位置的y值
double ad=aw-answ;
if(ad<0) //新值小于原值,接受
ansx=ax,answ=aw;
else if(exp(-ad/t)*RAND_MAX>rand()) //新值大于原值,根据概率接受
ansx=ax;
t*=down;
void solve()
cin>>n>>m>>p;
p*=1e-4;
ansx=n+m,answ=fun(ansx);
//cout<<ansx<<" "<<answ<<endl;
sa();
//cout<<ansx<<endl;
cout<<fixed<<setprecision(12)<<fun(ansx)<<endl;
signed main()
ios;
int T;cin>>T;
while(T--)
solve();
return 0;
E. Evil Coordinate
想了一个100多行的假代码后,终于想到一个全排列的好方法。
复杂度:O(24*N)
统计各个方向出现的次数,再对LRUD全排列,构造出不同路径,选择一个满足的。
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\\n'
const int N = 1e6+100;
int t,mx,my,n;
unordered_map<char,int>mp;
signed main()
//cin.tie(0);ios::sync_with_stdio(0);cout.tie(0);
cin>>t;
while(t--)
char s[4]='D','L','R','U';
sort(s,s+4);
mp.clear();
cin>>mx>>my;
string ss;cin>>ss;
if(mx==0&&my==0)
cout<<"Impossible"<<endl;continue;
n=ss.length();
for(int i=0;i<n;i++) mp[ss[i]]++;
int flag=1;
do
string ans="";
int x=0,y=0,g=0;
for(int i=0;i<4;i++)
if(s[i]=='D')
for(int j=mp['D'];j>=1;j--)
y--;
if(x==mx&&y==my)
g=1;break;
for(int j=1;j<=mp['D'];j++) ans+='D';
else if(s[i]=='L')
for(int j=mp['L'];j>=1;j--)
x--;
if(x==mx&&y==my)
g=1;break;
for(int j=1;j<=mp['L'];j++) ans+='L';
else if(s[i]=='R')
for(int j=mp['R'];j>=1;j--)
x++;
if(x==mx&&y==my)
g=1;break;
for(int j=1;j<=mp['R'];j++) ans+='R';
else if(s[i]=='U')
for(int j=mp['U'];j>=1;j--)
y++;
if(x==mx&&y==my)
g=1;break;
for(int j=1;j<=mp['U'];j++) ans+='U';
if(g==1) continue;
flag=0;
cout<<ans<<endl;
break;
while(next_permutation(s,s+4));
if(flag)
cout<<"Impossible"<<endl;
return 0;
以上是关于20南京站补题(EF)+cf数学的主要内容,如果未能解决你的问题,请参考以下文章