Codeforces 614

A

Problem description

求r到l间的是k的幂的数

Data Limit:1 ≤ l ≤ r ≤ 10e18, 2 ≤ k ≤ 10e9 Time Limit: 1s

Solution

暴力求,注意要用long long 为防止前一个数*k后爆long long,可以判一下1e18/k是否大于前一个数

Code

#include<cstdio>
long long r,l,k,n,i,j,t,t1;
int main()
{
    bool bo=false;
    scanf("%lld%lld%lld",&l,&r,&k);
    t=1;
    while (t<=r)
    {
        if (t>=l&&t<=r)
        {
            printf("%lld ",t);
            bo=true;
        }
        t1=t;                    
        t=t*k;                    
        if (t/k!=t1)break;
    }
    long long tt=-1;
    if (!bo)printf("%lld",tt);
    return 0;
}

B

Problem description

求n个数的乘积,但n个数中至少有n-1个美丽数 美丽数是最多有一个1,其他是0的数

Data Limit: 1 ≤ n ≤ 100 000Time Limit: 1s

Solution

首先,由于数可能很大,不能用long long读,要用字符串 然后通过找空格挑出n个数,判断末尾共有几个0,再找出那个普通数,在后面加0即可. 注意特判没有普通数的情况

Code

var s,t,ans:ansistring;
    i,j,n,tt,l:longint;
begin
  readln(n);
  readln(t);
  t:=t+' ';
  for l:=1 to n do
  begin
    s:=copy(t,1,pos(' ',t)-1);
    if s[1]='0' then
    begin
      write(0);
      halt;
    end;
    while s[length(s)]='0' do
    begin
      inc(tt);
      delete(s,length(s),1);
    end;
    if (length(s)<>1)or(s[1]<>'1')then
    ans:=s;
    delete(t,1,pos(' ',t));
    if l<>n then while (t[1]=' ') do delete(t,1,1);
  end;
  write(ans);
  if ans='' then write(1);
  for i:=1 to tt do write(0);
end.

C

Problem description

给一个多边形的n个点与旋转中心,求多边形经过的路径面积

Data Limit:3<=n <= 1e5 Time Limit: 1s

Solution

易得路径是一个环,求最大半径和最小半径然后套公式 注意:最大半径一定是顶点到旋转中心的距离,但最小半径可能是点到边的垂线段长

Code

#include<cstdio>
#include<cmath>
using namespace std;
long long px,py,x[1000000],y[1000000],n,i,j,ans1[10000],pi,lp,lans,hh,p[1000000],lll[10000],ll;
double l1[100][10],d;
double max,min,ans;
double PointToSegDist(double x, double y, double x1, double y1, double x2, double y2)
{
double cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1);
if (cross <= 0) return sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));

double d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
if (cross >= d2) return sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2));
 
l1[i][1]=y1-y2;
l1[i][2]=x2-x1;
l1[i][3]=-l1[i][1]*x1-l1[i][2]*y1;
d=(abs(l1[i][1]*px+l1[i][2]*py+l1[i][3]))/sqrt(l1[i][1]*l1[i][1]+l1[i][2]*l1[i][2]);
return(d);
}
int main()
{
    scanf("%lld%lld%lld",&n,&px,&py);max=-10000;min=10000000000000;
    for (i=1;i<=n;i++)
    {
        scanf("%lld%lld",&x[i],&y[i]);
        d=(px-x[i])*(px-x[i])+(py-y[i])*(py-y[i]);
        if (d>=max)max=d;
        if (d<=min)min=d;
    }
    for (i=2;i<=n;i++)
    {
        
        d=PointToSegDist(px,py,x[i],y[i], x[i-1], y[i-1]);
        d=d*d;
        if (d>=max)max=d;
        if (d<=min)min=d;
    }
    d=PointToSegDist(px,py,x[1],y[1], x[n], y[n]);
    d=d*d;
    if (d>=max)max=d;
    if (d<=min)min=d;
    ans=(max-min)*3.1415926535897932384626433;
    printf("%.18f",ans);
    
    return 0;
}

D

Problem description

有n个技能,给出初始等级和金币m(一金可以给一个技能升一级),求出最大威力. 威力:满级技能的个数(每个技能满级相同为A)乘mp(给出)+最低等级的技能等级乘mc(给出).

Data Limit:1 ≤ n ≤ 100 000, 1 ≤ A ≤ 109, 0 ≤ cf, cm ≤ 1000, 0 ≤ m ≤ 1015 Time Limit: 1s

Solution

按等级排序,从后向前枚举升满的技能数,然后二分求出剩下的金币可以做到的最低技能等级的最大值,然后求出此时威力.

Code

#include<cstdio>   
#include<iostream>  
#include<algorithm>  
using namespace std;  
#define MS(x,y) memset(x,y,sizeof(x))  
#define MC(x,y) memcpy(x,y,sizeof(x))  
#define MP(x,y) make_pair(x,y)  
#define ls o<<1  
#define rs o<<1|1  
typedef long long LL;  
typedef unsigned long long UL;  
typedef unsigned int UI;  
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }  
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }  
const int N = 1e5 + 10, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;  
int n; LL m;  
int A; LL cf, cm;  
LL sum[N];  
struct Skill  
{  
    int v, o;  
}a[N];  
bool cmp1(Skill a, Skill b)  
{  
    return a.v < b.v;  
}  
bool cmp2(Skill a, Skill b)  
{  
    return a.o < b.o;  
}  
int solve(int R, LL now)  
{  
    if (R == 0)return A;  
    int l = 1;  
    int r = R;  
    while (l < r)  
    {  
        int mid = (l + r + 1) >> 1;  
        LL need = (LL)a[mid].v * mid - sum[mid];
        if (need > now)r = mid - 1;  
        else l = mid;  
    }  
    LL need = (LL)a[l].v*l - sum[l];  
    LL more = (now - need) / l;  
    return min((LL)A, a[l].v + more);  
}  
int main()  
{  
    while (~scanf("%d%d%lld%lld%lld", &n, &A, &cf, &cm, &m))  
    {  
        for (int i = 1; i <= n; ++i) { scanf("%d", &a[i].v); a[i].o = i; }  
        sort(a + 1, a + n + 1, cmp1); a[n + 1].v = A;  
        for (int i = 1; i <= n; ++i)sum[i] = sum[i - 1] + a[i].v;  
        LL ans = -1;  
        LL cost = 0;  
        int v, p;  
        for (int i = n; i >= 0; --i)  
        {  
            cost += A - a[i + 1].v;  
            if (cost > m)break;  
            int minv = solve(i, m - cost);  
            LL tmp = minv*cm + (n - i)*cf;  
            if (tmp > ans)  
            {  
                ans = tmp;  
                p = i;  
                v = minv;  
            }  
        }  
  
        printf("%lld
", ans);  
        for (int i = n; i > p; --i)a[i].v = A;  
        for (int i = 1; i <= p; ++i)gmax(a[i].v, v);  
        sort(a + 1, a + n + 1, cmp2);  
        for (int i = 1; i <= n; ++i)printf("%d ", a[i].v); puts("");  
    }  
    return 0;  
} 
原文地址:https://www.cnblogs.com/Orange-User/p/7470539.html