记一些比较有意思的题
第一题:2020多校第6场第一题
题目链接
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
const int mod=1e9+7;
typedef long long ll;
inline ll read()
{
ll s=0,w=1;char ch=getchar();
while(ch<48||ch>57){if(ch=='-')w=-1;ch=getchar();}
while(ch>=48&&ch<=57)s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
return s*w;
}
ll qkpow(ll a,ll b)
{
ll sum=1;
while(b>0)
{
if(b&1)
sum=sum*a%mod;
a=a*a%mod;
b>>=1;
}
return sum%mod;
}
int add(ll x, ll y)
{
ll temp=x+y;
if(temp>mod)return temp-mod;
else if(temp<0)return temp+mod;
return temp;
}
int t,n,y,s[N],inv[N],sum[N],ans;
int main()
{
inv[1]=1;
for(int i=2;i<N;++i)inv[i]=1ll*(mod-mod/i)*inv[mod %i]%mod;
t=read();
while(t--)
{
ans=0;
n=read();
for(int i=1;i<=n;i++)
{
s[i]=read();
s[i]=add(s[i],s[i-1]);
}
for(int i=1;i<=n;i++)
{
sum[i]=add(sum[i-1],s[n-i+1]-s[i-1]);
ans=add(ans,1ll*sum[i]*inv[i]%mod);
}
y=qkpow(1ll*(1+n)*n/2%mod,mod-2);
cout<<1ll*ans*y%mod<<endl;
}
return 0;
}
第二题:题目链接
解题思路:
先拿几个数组试试
比如n=8,k=3;
1 2 3 4 5 6 7 8
变成
4 5 6 7 8 1 2 3
最快的是3次
第一次[1,8]翻转 8 7 6 5 4 3 2 1
第二次[1,5]翻转 4 5 6 7 8 3 2 1
第三次[6,8]翻转 4 5 6 7 8 1 2 3
你会发现最多就3次
再比如 n=8,k=2(这种只用2次就行了,但是很难想到)
第一次[2,8]翻转 1 8 7 6 5 4 3 2
第二次[1,7]翻转 3 4 5 6 7 8 1 2
只用2次
再比如 n=8,k=1
第一次[1,8]翻转 8 7 6 5 4 3 2 1
第二次[1,7]翻转 2 3 4 5 6 7 8 1
也是用2次
在多举几组就能发现规律
规律见代码
class Solution {
public:
int solve(int n, int k) {
k%=n;
if(k==0)return 0;
else if(n==2)return 1;
if(k==1||k==2||n-k==1||n-k==2)return 2;return 3;
}
};
第三题:题目链接
思路:涂黑一定是连着涂黑的
只要遍历一遍维护最大值即可
具体思路见代码
class Solution {
public:
int solve(int n, int m, vector<int>& a) {
int l=1,ans=0,cnt=0;
for(int i=1;i<=n;++i){
cnt+=1-a[i];
while(cnt>m) cnt-=1-a[l],++l;
ans=max(ans,i-l+1);
}
return ans;
}
};
第四题:题目链接
思路:在dij里多加一个欠债人第i天花的钱,然后在主函数里遍历一遍第i天到n城市花的最少的钱,记录最小值即可。
代码如下
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
const ll inf=0x3f3f3f3f;
struct node{
int d,u,w;
bool operator< (const node &p)const{
return w>p.w;
}
};
int n,m,k;
vector<pair<int,int>>g[N];
int dis[1010][1010],a[N];
void dij()
{
memset(dis,inf,sizeof dis);
dis[0][1]=0;
priority_queue<node>q;
q.push((node){0,1,0});
while(!q.empty())
{
node p=q.top();
q.pop();
int u=p.u,d=p.d;
if(p.w>dis[d][u])continue;
for(auto i:g[u])
{
int v=i.first,w=i.second;
if(d+1<=k&&dis[d+1][v]>dis[d][u]+w+a[d+1])
{
dis[d+1][v]=dis[d][u]+w+a[d+1];
q.push((node){d+1,v,dis[d+1][v]});
}
}
}
}
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=m;i++)
{
int u,v,w;
cin>>u>>v>>w;
g[u].push_back(make_pair(v,w));
g[v].push_back(make_pair(u,w));
}
for(int i=1;i<=k;i++)cin>>a[i];
dij();
int ans=inf;
for(int i=1;i<=k;i++)ans=min(ans,dis[i][n]);
if(ans==inf)cout<<-1<<endl;
else cout<<ans<<endl;
return 0;
}