Codeforces Round #326 (Div. 2)

来源:互联网 发布:Apache 配置转发 编辑:程序博客网 时间:2024/05/16 10:21

传送门:A. Duff and Meat     (简单贪心)

题意:给出n,表示要经过n个地点
接下来n行,【ai,pi】 ai表示当天必须吃ai个食物,pi表示一单位食物要pi块钱


思路:直接贪心,用一个变量记录最便宜的价格,如果当前pi大于它,则之前用最便宜的价格买上当前pi的份,反之,用pi更新最便宜价格,并用新的价格购买食物;

#include<bits/stdc++.h>using  namespace  std;const   int  maxn=1e5+10;int  a[maxn],p[maxn];int  n;int  main(){    freopen("in.txt", "r", stdin);    freopen("out.txt", "w", stdout);    while(~scanf("%d",&n)){        for(int  i=0 ; i<n ; i++){            scanf("%d %d",&a[i],&p[i]);        }            int mincost=101,ans=0;            for(int i=0 ; i<n ; i++){               if(mincost>p[i])mincost=p[i];               ans+=a[i]*mincost;            }        printf("%d\n",ans);    }    return 0;}

传送门:B. Duff in Love    (数学)

题意:
给你一个数 n,然后找它所有因子数中没有 平方数 的最大值

思路:每次寻找能被整除的平方数,再除去后递归

#include<bits/stdc++.h>#define ll __int64using  namespace  std;ll n;ll  f(ll n){    ll i,tmp;    for(i=2 ; i*i<=n ; i++){        if(n%(i*i)==0){            tmp=i;            break;        }    }    if(i*i>n)return n;    else return f(n/tmp);}int  main(){    freopen("in.txt", "r", stdin);    freopen("out.txt", "w", stdout);    while(~scanf("%I64d",&n)){        printf("%I64d\n",f(n));    }    return 0;}

另附不用递归的写法:

<span style="font-size:12px;">#include <bits/stdc++.h>#define ll __int64using  namespace  std;ll n;int main(){  scanf("%I64d",&n);  ll ans=1;  for(ll i=2 ; i*i<=n ; i++){    if(n%i==0){      ans*=i;      while(n%i==0)n/=i;    }  }  printf("%I64d\n",ans*n);  return 0;}</span>


传送门:C. Duff and Weight Lifting (数学)

题意:有n个数a[i]代表2a[i],每次可以去掉若干个数当它们和为2的幂次时。问最少需要多少次。

思路:一直合并就可以了,因为当a!=b时,2a+2b肯定不是2的幂次。

#include<bits/stdc++.h>using  namespace  std;const  int maxn=1e7+10;int  n;int vis[maxn];int   main(){//    freopen("in.txt", "r", stdin);//    freopen("out.txt", "w", stdout);    while(~scanf("%d",&n)){        memset(vis,0,sizeof(vis));        int x,len=0;        for(int  i=0; i<n ;i++){            scanf("%d",&x);            vis[x]++;            len=max(len,x);        }        for(int i=0 ; i<=len ; i++){            if(vis[i]%2==0){                vis[i+1]+=vis[i]/2;                vis[i]=0;            }            else{                vis[i+1]+=vis[i]/2;                vis[i]=1;            }        }        len++;        while(1) {            if(vis[len] == 1 || vis[len] == 0) {                break;            }            if(vis[len] & 1) {                vis[len+1] += vis[len] / 2;                vis[len] = 1;            }            else {                vis[len+1] += vis[len] / 2;                vis[len] = 0;            }            len++;        }        int ans=0;        for(int i=0 ; i<=len ; i++){            if(vis[i]!=0)ans++;        }        printf("%d\n",ans);    }    return  0;}

解题历程:为了防止切CF题A,B题时脑子有坑,所以果断先切C题,一看数据不大就用map,结果老是在第38个数据上超时,

调了半个小时之后一怒之下改成数组就AC了_(:зゝ∠),后来看了一下数据都是wi接近最大上限的数据,map内部是红黑树,

它可以在O(log n)时间内做查找,但是在扫一遍n的话复杂度就是O(nlog n),所以超时也是可能的。


1 0
原创粉丝点击