本篇题解只有:A、D、E、F、G、H、J、K、L(后续学会B、C、I 会补上去的
出题人预估难度:J<K<G<E<F<H<L<D<C<I<A<B
实际难度:J<E<G<K<F<A<H<L<D<I<C<B
目录
A | 你也喜欢数学吗 |
比赛时通过打表 直接推出公式
公式推导:
会爆long long注意取余,除法取余要用逆元
#include<bits/stdc++.h>
using namespace std;
#define debug(a) cout<<#a<<"="<<a<<"\n";
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
#define lowbit(x) ((x) & - (x))
typedef pair<int,int> PII;
const double pi = acos(-1.);
const int mod=1000000007;
int n,m;
string str;
int qmi(int a,int b,int q)
{
int res=1%q;
while(b)
{
if(b&1)res=res*a%q;
a=a*a%q;
b>>=1;
}
return res;
}
void solve()
{
cin>>n;
cout<<(((n%mod)*((n+1)%mod))%mod*(((n%mod)+2)%mod)%mod*qmi(6,mod-2,mod))%mod;
}
signed main()
{
IOS
int T=1;
//cin>>T;
while(T--) solve();
return 0;
}
D | 松鼠回家 |
根据题意求最大的那个点扣除的数量尽可能小 显然需要用到二分,二分最终扣除松果的数量 来找到最优满足解
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset((a),(b),sizeof(a))
#define debug(a) cout<<#a<<"="<<a<<"\n";
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
typedef pair<int,int> PII;
const double pi = acos(-1.);
const int N=1e5+10;
int n,m,st,ed,s;
int a[N];
string str;
int h[N],ne[N],e[N],w[N],idx;
void add(int a,int b,int c)
{
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
int dist[N];
bool vis[N];
bool check(int mid)//dijkstra最短图
{
mem(dist,0x3f);mem(vis,false);
priority_queue<PII,vector<PII>,greater<PII> > q;
q.push({0,st});
dist[st]=0;
if(a[st]>mid) return false;
//当开始点扣除的松果数量大于mid,该情况不满足
while(q.size())
{
auto t=q.top();
q.pop();
if(vis[t.second])continue;
vis[t.second]=true;
for(int i=h[t.second];i!=-1;i=ne[i])
{
int j=e[i];
if(dist[j]>t.first+w[i]&&a[j]<=mid)//每次到达的点扣除松果数应小于mid
{
dist[j]=t.first+w[i];
q.push({dist[j],j});
}
}
}
//当最终点没办法到达 或 到底所需体力大于开始时候的体力 该情况不满足
if(dist[ed]==0x3f3f3f3f||dist[ed]>s)return false;
return true;
}
void solve()
{
cin>>n>>m>>st>>ed>>s;
for(int i=1;i<=n;i++)cin>>a[i];
mem(h,-1);
while(m--)
{
int x,y,z;
cin>>x>>y>>z;
add(x,y,z);
add(y,x,z);//无向图
}
int l=1,r=(int)1e7;
while(l<r)
{
int mid=(l+r)>>1;
if(check(mid))r=mid;
else l=mid+1;
}
if(l==(int)1e7)cout<<"-1\n";
else cout<<l<<"\n";
}
signed main()
{
IOS
int T=1;
//cin>>T;
while(T--) solve();
return 0;
}
E | 动物朋友 |
根据题意求 有多少种所选的连续的动物朋友的快乐值刚好为m,先预处理前缀和,再直接枚举每个动物,充当连续动物朋友的左边界,再使用二分找刚好满足的情况即可
#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset((a),(b),sizeof(a))
#define debug(a) cout<<#a<<"="<<a<<"\n";
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
#define lowbit(x) ((x) & - (x))
typedef pair<int,int> PII;
const double pi = acos(-1.);
int n,m;
string str;
void solve()
{
cin>>n>>m;
vector<int> a(n+1),s(n+1);
for(int i=1;i<=n;i++)
{
cin>>a[i];
s[i]=s[i-1]+a[i];
}
int cnt=0;
for(int i=1;i<=n;i++)
{
int l=i,r=n;
while(l<r)
{
int mid=(l+r)>>1;
if(s[mid]-s[i-1]>=m)r=mid;
else l=mid+1;
}
if(s[l]-s[i-1]==m)cnt++;
}
cout<<cnt;
}
signed main()
{
IOS
int T=1;
//cin>>T;
while(T--) solve();
return 0;
}
F | 松鼠排序 |
根据题意对于每个位置,在并查集中把 a[i] 和 i 两个点合并,设最终合并大小为cnt,则即为答案。
#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset((a),(b),sizeof(a))
#define debug(a) cout<<#a<<"="<<a<<"\n";
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
#define lowbit(x) ((x) & - (x))
typedef pair<int,int> PII;
const double pi = acos(-1.);
const int N=1e5+10;
int p[N];
int find(int x)
{
return x==p[x]?p[x]:p[x]=find(p[x]);
}
void solve()
{
int n;cin>>n;
for(int i=1;i<=n;i++)p[i]=i;
int cnt=0;
for(int i=1;i<=n;i++)
{
int x;cin>>x;
if(find(x)!=find(i))
{
p[find(x)]=find(i);
cnt++;
}
}
cout<<cnt;
}
signed main()
{
IOS
int T=1;
//cin>>T;
while(T--) solve();
return 0;
}
G | Reverse |
算是思维题吧
翻转后最长1长度 即为字符串连续的1数量 最大值和次大值相加之和
#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset((a),(b),sizeof(a))
#define debug(a) cout<<#a<<"="<<a<<"\n";
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
#define lowbit(x) ((x) & - (x))
typedef pair<int,int> PII;
const double pi = acos(-1.);
const int N=1e6+10;
int a[N];
int n,m,k;
string str;
void solve()
{
cin>>n>>str;
int ans=0;
for(int i=0;i<n;i++)
{
if(str[i]=='1')
{
ans++;
}
else if(str[i]=='0')
{
a[k++]=ans;
ans=0;
}
}
if(ans)a[k++]=ans;
sort(a,a+k,greater<int>());
cout<<a[0]+a[1];
}
signed main()
{
IOS
int T=1;
//cin>>T;
while(T--) solve();
return 0;
}
H | 迷宫探险 |
正常bfs题,但中间加了一个跳板 ,可以直接跳w距离且不花时间,因此就要在分情况讨论了
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset((a),(b),sizeof(a))
#define debug(a) cout<<#a<<"="<<a<<"\n";
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define lowbit(x) ((x) & - (x))
typedef pair<int,int> PII;
const double pi = acos(-1.);
const int N=3010;
int n,m,k,x,y,w,nx,ny;
char ma[N][N];
int dist[N][N];
string str;
int dx[]={-1,0,1,0},dy[]={0,1,0,-1};
map<PII,int> mp;
void bfs()
{
mem(dist,0x3f);
queue<PII> q;
q.push({1,1});
dist[1][1]=0;
while(q.size())
{
auto t=q.front();
q.pop();
if(ma[t.first][t.second]=='.')
{
for(int i=0;i<4;i++)
{
nx=t.first+dx[i],ny=t.second+dy[i];
//dist[nx][ny]<=dist[t.first][t.second]+1 走过已经走过的 即不再走
if(nx<1||nx>n||ny<1||ny>m||ma[nx][ny]=='#'||dist[nx][ny]<=dist[t.first][t.second]+1)continue;
dist[nx][ny]=dist[t.first][t.second]+1;
q.push({nx,ny});
}
}
else
{
for(int i=0;i<4;i++)
{
nx=t.first+dx[i]*mp[{t.first,t.second}],ny=t.second+dy[i]*mp[{t.first,t.second}];
if(nx<1||nx>n||ny<1||ny>m||ma[nx][ny]=='#'||dist[nx][ny]<=dist[t.first][t.second])continue;
dist[nx][ny]=dist[t.first][t.second];
q.push({nx,ny});
}
}
}
}
void solve()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>ma[i][j];
cin>>k;
while(k--)
{
cin>>x>>y>>w;
mp[{x,y}]=w;
}
bfs();
if(dist[n][m]==0x3f3f3f3f)cout<<"-1\n";
else cout<<dist[n][m]<<"\n";
}
signed main()
{
IOS
int T=1;
//cin>>T;
while(T--) solve();
return 0;
}
J | 合唱比赛 |
真签到题
#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset((a),(b),sizeof(a))
#define debug(a) cout<<#a<<"="<<a<<"\n";
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
#define lowbit(x) ((x) & - (x))
typedef pair<int,int> PII;
const double pi = acos(-1.);
int n,m;
string str;
void solve()
{
cin>>n;
vector<int> a(n);
for(int i=0;i<n;i++)cin>>a[i];
sort(a.begin(),a.end());
int sum=accumulate(a.begin(),a.end(),0);
cout<<fixed<<setprecision(6)<<1.0*((sum-a[n-1])*1.0/(n-1))<<" ";
cout<<fixed<<setprecision(6)<<1.0*((sum-a[0])*1.0/(n-1))<<" ";
}
signed main()
{
IOS
int T=1;
//cin>>T;
while(T--) solve();
return 0;
}
K | 以撒和隐藏房间 |
模拟题
#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset((a),(b),sizeof(a))
#define debug(a) cout<<#a<<"="<<a<<"\n";
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
#define lowbit(x) ((x) & - (x))
typedef pair<int,int> PII;
const double pi = acos(-1.);
const int N=1010;
char ma[N][N];
int n,m,c;
string str;
void solve()
{
mem(ma,'3');
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>ma[i][j];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(ma[i][j]=='0')
{
int ans=0;bool ok=true;
if(ma[i-1][j]=='1')ans++;
if(ma[i+1][j]=='1')ans++;
if(ma[i][j-1]=='1')ans++;
if(ma[i][j+1]=='1')ans++;
if(ma[i-1][j]=='2'||ma[i][j+1]=='2'||ma[i][j+1]=='2'||ma[i][j-1]=='2'||ma[i+1][j]=='2')ok=false;
if(ans==3&&ok)c++;
}
}
}
if(c)cout<<"YES\n"<<c;
else cout<<"NO\n";
}
signed main()
{
IOS
int T=1;
//cin>>T;
while(T--) solve();
return 0;
}
L | 中位数 |
算是树状数组的板子题了(如果会树状数组,就可以轻松解决
用数值数组维护每个数的个数,中位数即为k=(n+1)/2,也就是求第k大的数
有单调性,用二分可以轻松完成
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset((a),(b),sizeof(a))
#define debug(a) cout<<#a<<"="<<a<<"\n";
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
#define lowbit(x) ((x) & - (x))
typedef pair<int,int> PII;
const double pi = acos(-1.);
const int N=1e6+10;
int n,m,a[N],tr[N];
string str;
void add(int x,int c)
{
//这是要是N ,如果是n的话,会影响n-N之间的数,进而影响单调性
for(int i=x;i<=N;i+=lowbit(i))tr[i]+=c;
}
int ask(int x)
{
int res=0;
for(int i=x;i;i-=lowbit(i))res+=tr[i];
return res;
}
void solve()
{
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i],add(a[i],1);
int k=(n+1)/2;
while(m--)
{
int p,x;
cin>>p>>x;
add(a[p],-1);
a[p]=x;
add(x,1);
int l=1,r=1e6;
while(l<r)
{
int mid=(l+r)>>1;
if(ask(mid)>=k)r=mid;
else l=mid+1;
}
cout<<l<<"\n";
}
}
signed main()
{
IOS
int T=1;
//cin>>T;
while(T--) solve();
return 0;
}
如果有错误的地方,可以及时指出。