炮弹
按照题意模拟:
注意两点:
1.死循环,如果存在两个能量为0跳板,就会互相弹跳,停不下来,设置一个合理的循环上限,防止超时
2.时间复杂度:在最坏的情况下
k最开始为1,跳n次,k为2时,跳2/n次.....
所以在最坏的情况下时间复杂度\(O(\sum_{i=1}^{n}\frac{n}{i})=O(nlnn)\)是调和级数的时间复杂度
点击查看代码
#include<bits/stdc++.h>using namespace std;int n,s;
const int maxn=1e5+10;
struct node{int q,v;
}e[maxn];
int nex=1;
int ans=0;
bool flag[maxn];
int check[maxn][3];
int main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>n>>s;for(int i=1;i<=n;++i) cin>>e[i].q>>e[i].v;bool book=1;int cnt=0;while(s>=1 && s<=n && cnt<=n*26){// cout<<s<<endl;if(e[s].q==0){book=!book;nex+=e[s].v;}else {if(e[s].v<=nex && flag[s]==0)++ans,flag[s]=1;}s+=book?nex:(-1)*nex;++cnt;} cout<<ans<<endl;return 0;
}
平衡细菌
差分好题:
一旦从差分的角度思考该问题就相当简单,
\([l,n]\)依次加n-l,n-l+1,....,n
从差分的角度,差分数组b[l+1,n]的均+1
再差分一次,差分数组c[l]++和c[n+1]--
那么题意转化成差分的形式就是,经过多少次操作后,a全部为0,同时b全部为0,也就是c全部为0
所以操作一次对c数组的影响就是c[l]++,因此答案就是c数组的总和
注意因为有可能加的也是负数,我们统计c中数值取绝对值
点击查看代码
#include<bits/stdc++.h>using namespace std;#define int long long
const int maxn=2e5+10;
int n;
int a[maxn];
int b[maxn];
int c[maxn];
signed main(){cin>>n;for(int i=1;i<=n;++i) cin>>a[i];int ans=0;for(int i=1;i<=n;++i){b[i]=a[i]-a[i-1];c[i]=b[i]-b[i-1];ans+=abs(c[i]);}cout<<ans<<endl;return 0;}
回文游戏
思维题
谁先取完,谁赢
首先可以知道的是0 ~ 9肯定是回文数,所以轮到一个的数字是0~9时,就赢了
对于博弈的过程,每个人都想赢,所以不会想着取一个很大回文数,因为这样结果是很随机,没有把握,所以每个人尽量选择,一个0 ~ 9的数
对于一个末尾不是0的数,那么贝尔可以选取石使得末尾为0,埃尔希就会任意选择一个不为0且不大于9的数,如此轮回,最后贝尔会使石头变为0,赢得胜利,反之埃尔希赢
点击查看代码
#include<bits/stdc++.h>using namespace std;
int t;int n;
string s;
void solve(){cin>>s; if(s[s.length()-1]=='0') puts("E");else puts("B");return ;}
int main(){cin>>t;while(t--){solve();}return 0;
}
牛奶交换
最麻烦的事情,这是个环,需要特别注意
只有出现RL的时候,牛奶会在这两个捅之间循环,R左边的牛奶都会过来,L右边的牛奶也都会过来,记录每一边的牛奶,如果比时间少,那么全都损失,如果比时间多,那么只会损失时间数量的牛奶
点击查看代码
#include<bits/stdc++.h>using namespace std;
long long n,m;
string s;const int maxn=2e5+10;
long long a[maxn];
long long ans=0,tot=0;
int main(){cin>>n>>m;cin>>s;s=" "+s;for(int i=1;i<=n;++i) cin>>a[i],tot+=a[i];long long sum1=0,sum2=0;bool book=0;for(int i=1;i<n;++i){if(s[i]=='R' && s[1+i]=='L') book=1;if(s[i]=='L' && s[i+1]=='R') book=1;}if(!book){cout<<tot<<endl;return 0;}for(int i=1;i<=n;++i){if(s[i]=='R' && s[(i)%n+1]=='L'){int j=i-1;while(s[j]=='R'){sum1+=a[j];--j;if(j==0) j=n;}j=i%n+2;while(s[j]=='L' && j<=n){sum2+=a[j];++j;if(j==n+1) j=1;}ans+=min(sum1,m)+min(sum2,m);sum1=0,sum2=0;}}cout<<tot-ans<<endl;return 0;
}
最大限度地提高生产力
由于时间的数据范围不大,我们可以直接用后缀和预处理某个时刻之后还开着的农场,查询时就可以以O(1)的时间查询还开着的农场
点击查看代码
#include<bits/stdc++.h>using namespace std;
int n,q;
const int maxn=2e6+10;
int t[maxn],c[maxn];
int sum[maxn];int v,s;
int main(){cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);memset(sum,0,sizeof(sum));cin>>n>>q;for(int i=1;i<=n;++i) cin>>c[i];for(int i=1;i<=n;++i){cin>>t[i];if(c[i]-t[i]-1>=0)sum[c[i]-t[i]-1]++;}for(int i=2e6;i>=0;--i) sum[i]+=sum[i+1];while(q--){cin>>v>>s;if(sum[s]>=v) puts("YES");else puts("NO");}return 0;
}