比赛:点击打开链接
558A - Lala Land and Apple Trees
分析:从0坐标分开,负半轴一个数组,正半轴一个数组,来记录果树的左边和数量,可以用结构体数组来存储数据,其中少的一个半轴上的果树肯定会全被采光,而多的一边树上会多采一棵树。struct p{
int num,x;
}
p neg[105],pos[105];
这样表示更容易排序,用一个sort就可以了,我下边的代码用的是冒泡,稍微麻烦点
#include<bits/stdc++.h>
using namespace std;
int n;
int pos[100],neg[100],posflag[100],negflag[100];
int main()
{
scanf("%d",&n);
int x,a,numpos=0,numneg=0;
for(int i=0;i<n;i++){
scanf("%d%d",&x,&a);
if(x>0){posflag[numpos]=x;pos[numpos++]=a;}
else {negflag[numneg]=x;neg[numneg++]=a;}
}
int sum=0;
if(numpos>numneg){
for(int ii=0;ii<numpos-1;ii++)
for(int j=0;j<numpos-1-ii;j++){
if(posflag[j]>posflag[j+1]){
int t=posflag[j];posflag[j]=posflag[j+1];posflag[j+1]=t;
t=pos[j];pos[j]=pos[j+1];pos[j+1]=t;
}
}
for(int i=0;i<numneg;i++){
sum+=pos[i]+neg[i];
}
sum+=pos[numneg];
}
else if(numpos<numneg){
for(int ii=0;ii<numneg-1;ii++)
for(int j=0;j<numneg-ii-1;j++){
if(negflag[j]<negflag[j+1]){
int t=negflag[j];negflag[j]=negflag[j+1];negflag[j+1]=t;
t=neg[j];neg[j]=neg[j+1];neg[j+1]=t;
}
}
for(int i=0;i<numpos;i++)
sum+=pos[i]+neg[i];
sum+=neg[numpos];
}
else {
for(int i=0;i<numpos;i++)
sum+=pos[i]+neg[i];
}
printf("%d\n",sum);
return 0;
}
558B - Amr and The Large Array
题意:找出一个数组中出现次数最多而且包含数最少(即最大小标—最小下标最小)的数
分析:如下代码所示,构造一个结构体数组来保存每个点的信息,然后排序处理一下OK
#include<bits/stdc++.h>
using namespace std;
struct p
{
int count=0,first,last;
bool flag=0;
}num[1000005];
int n,a;
bool cmp(p a,p b)
{
if(a.count<b.count)return true;
else if(a.count>b.count) return false;
return (a.last-a.first)>(b.last-b.first);
}
int main()
{
scanf("%d",&n);
int maxa=1;
for(int i=1;i<=n;i++){
scanf("%d",&a);
if(num[a].flag){
num[a].last=i;
num[a].count++;
}
else{
num[a].count++;
num[a].first=i;
num[a].flag=1;
}
if(maxa<a)maxa=a;
}
sort(num+1,num+maxa+1,cmp);
if(num[maxa].first==0||num[maxa].last==0)cout<<"1 1"<<endl;//如果全都
else
cout<<num[maxa].first<<' '<<num[maxa].last<<endl;
return 0;
}
558C - Amr and Chemistry
题意:n个数字,对每个数字可以进行两种操作:num*2与num/2(向下取整),求:让n个数相等最少需要操作多少次分析:*2和/2,接容易发现可以用移位操作完成,那么可以枚举每个数字可以到达的数字并且记录下所需要的操作步数,最后统计每个数字vis出现次数为n,并且操作步数最小的数。因为奇数/2,向下取整,所以如果是奇数还可以/2*2,,来到达不同的数字
比较详细的分析:here
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
int num[(int)1e5+5],vis[(int)1e5+5];
void solve(int val)
{
int t=val<<1,step=1;
while(t<=(int)1e5){
vis[t]++;
num[t]+=step;
step++;
t<<=1;
}
t=val,step=0;
while(t>0){
vis[t]++;
num[t]+=step;
if((t&1)&&t>1){
int tt=t/2*2,tstep=step+2;
while(tt<=(int)1e5){
vis[tt]++;
num[tt]+=tstep;
tt<<=1;
tstep++;
}
}
step++;
t>>=1;
}
}
int main()
{
int n,val;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&val);
solve(val);
}
int ans=INF;
for(int i=1;i<=(int)1e5;i++){
if(vis[i]==n)
ans=min(ans,num[i]);
}
printf("%d\n",ans);
}