第一题 Majority Opinion
题目描述
输入格式:
输入保证所有测试用例的 之和不超过 。
输出格式:
输入样例:
输出样例:
题目大意/程序目标:
每次运算选定一个区间,若在此区间内有一个数字 n 的数量 大于区间总数字数量的一半(如区间有16个数字,则至少需要有9个相同的数字 n ),那么此区间的数都变成 n ,进行多次运算,最后所有的数字都变成相同的数,问这个数能是多少。
思路
可以证明,一个数想成为答案,必须在任意3个连续数字中,至少有两个。
证明方法:3中有2,就能有3,就能有4,...,就能有n,4中有2但3中无2(如1001001),就不能成为答案
就做完了。
代码
#include<bits/stdc++.h>
using namespace std;
int T,n,t[100010],x,y,z,m,ans[100010];
//t数组用于维护区间,ans数组表示这个数是否能成为答案
int main(){
cin>>T;
while(T--){
memset(ans,0,sizeof(ans));
memset(t,0,sizeof(t));
cin>>n>>x>>y;
t[x]++,t[y]++;
if(n==2){//特判
if(x==y) cout<<x<<'\n';
else cout<<-1<<'\n';
continue;
}
if(x==y) ans[x]=1;//这个不能漏
queue<int>q;
q.push(x),q.push(y);
for(int i=3;i<=n;i++){
cin>>x;
t[x]++;
q.push(x);
if(t[x]>=2) ans[x]=1;
t[q.front()]--;q.pop();
}
bool f=0;
for(int i=1;i<=n;i++)
if(ans[i]){
if(f) cout<<' '<<i;
else f=1,cout<<i;
}
if(!f) cout<<-1;
cout<<'\n';
}
return 0;
}
第二题Cannonball
题目描述
输入格式:
输出格式:
输入样例:
输出样例:
第二题直接模拟只有75分(不要问我怎么知道的)猜猜我为什么不写题解
第三题 Balancing Bacteria
题目描述
输入格式:
输出格式:
输入样例1:
输出样例1:
输入样例2:
输出样例2:
题目大意/程序目标:
见思路
思路
做好心理准备,即使你看得懂思路也可能看不懂代码!!!
差分
这是一道好题。
可以发现:一次计算过程就相当于 (1,2,3,...,L-1,L),而将此序列差分一下就是(1,1,1,...,1,1),看起来很好看,所以选定思路
有了差分这个思路后,我们将原数组差分,得到数组b,差分有一个特性就是差分数组求前缀和是原数组。可以证明 将b数组后L位(1,1,1,...,1,1)后的前缀必定=原数组 (1,2,3,...,L-1,L),所以就可以把 题目:原数组 (1,2,3,...,L-1,L)重复多次变成0,转化为差分数组 (1,1,1,...,1,1)重复多次变成0
因为每个数都是独立的,这一位加了多少和上一位是没关系的,所以我们可以直接从第一位开始。
因为每次差分数组加减都是从某一位到最后一位都加1的,所以这一位加了多少,下一位也是加多少,又因为我们是从第一位开始的,那么当b[i-1]=0时,后面的数一定都减了b[i-1],那么b[i]想等于0就得减去b[i]-b[i-1],就是进行b[i]-b[i-1]次操作。
如果不好理解的话,我们先设一个k表示前面已经用了k此操作,每次操作都是在前面进行的,所以后面的数一定都减了k,b[i-1]想等于0就得减去b[i-1],原来就减了k,就只用减b[i-1]-k。到i+1时,k就变成k+(b[i-1]-k),(原来的次数+新增的次数)刚好是b[i-1],所以每一次k=b[i],就不用k了,b[i]=b[i]-k=b[i]-b[i-1],就是进行b[i]-b[i-1]次操作
注意:要用LL,因为不知b[i]和b[i-1]谁大谁小,所以要用abs
#include<bits/stdc++.h>
using namespace std;
long long n,a[200010],b[200010],ans;
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],b[i]=a[i]-a[i-1],ans+=abs(b[i]-b[i-1]);
cout<<ans;
return 0;
}
此代码还能简化:
#include<bits/stdc++.h>
using namespace std;
long long n,ax,ay,bx,by,ans;
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>ay,by=ay-ax,ans+=abs(by-bx),ax=ay,bx=by;
cout<<ans;
return 0;
}
最终时间复杂度O(n),空间复杂度O(1)