$$ \newcommand{\seq}[2]{{#1}_{1},{#1}_{2},\cdots,{#1}_{#2}} \newcommand{\num}[1]{1,2,\cdots,#1} \newcommand{\stra}[2]{\begin{bmatrix}#1 \\ #2\end{bmatrix}} \newcommand{\strb}[2]{\begin{Bmatrix}#1 \\ #2\end{Bmatrix}} \newcommand{\dw}[1]{\underline{#1}} \newcommand{\up}[1]{\overline{#1}} $$

Codeforces 379 (Good Bye 2013)

379 C

题意

给你一个数组,现在可以将数组中的某个元素加上任意正整数,可以操作无限次,要求操作完后数组不能有重复元素,且元素之和最小。输出更改后的数组。
( \(1\le n\le 3·10^5\) )

Examples

Input
3
5 1 1
Output
5 1 2
Input
1
1000000000
Output
1000000000

排序,维护一个变量mx,a[i]=max(a[i],mx),mx=a[i]+1。

379 D

题意

有两个串 \(s_1,s_2\) ,现在给你它们的长度,要求构造出这两个串,使 \(s_n\) 中"AC"的出现次数恰好为 \(x\)
\(s_i=s_{i-2}+s_{i-1}(i≥3)\) (此处 \(+\) 为字符串连接)
( \(3 ≤ k ≤ 50,0 ≤ x ≤ 10^9,1 ≤ n, m ≤ 100\) )

Examples

Input
3 2 2 2
Output
AC
AC
Input
3 3 2 2
Output
Happy new year!
Input
3 0 2 2
Output
AA
AA
Input
4 3 2 1
Output
Happy new year!
Input
4 2 2 1
Output
Happy new year!

暴力分类讨论(X表示除A、C之外的任意字符)
1.
X...X
X...X
2.
C...X
X...A
3.
X...A
C...X
4.
X...X
C...A
5.
X...A
C...A
6.
C...A
C...A

Code 1

#include<bits/stdc++.h>
using namespace std;
long long f[103];
int k,x,n,m;
char s[103],t[103];
bool check(int mo){
    int p=3;
    while(p<k){
        p++;
        f[p]=f[p-2]+f[p-1];
        if(mo==2){
            if((p&1)==0)f[p]++;
        }
        else if(mo==4){
            f[p]++;
        }
        else if(mo==5){
            if(p&1)f[p]++;
        }
    }
    return f[p]==x;
}
int main(){
    scanf("%d%d%d%d",&k,&x,&n,&m);
    for(int i=0;i<=n;i++){
        for(int j=0;j<=m;j++){
            f[1]=(i>>1),f[2]=(j>>1),f[3]=f[1]+f[2];
            if(check(1)){
                int l;
                for(l=1;l<=i;l++)s[l]=(l&1?'A':'C');
                for(;l<=n;l++)s[l]='B';
                for(l=1;l<=j;l++)t[l]=(l&1?'A':'C');
                for(;l<=m;l++)t[l]='B';
                if(!((s[1]=='C'&&t[m]=='A')||(t[1]=='C'&&s[n]=='A')||(t[1]=='C'&&t[m]=='A'))){
                    puts(s+1),puts(t+1);
                    return 0;
                }
            }
            if(i<=n-1&&j<=m-1){
                f[1]=(i>>1),f[2]=(j>>1),f[3]=f[1]+f[2];
                if(check(2)){
                    int l;
                    s[1]='C';
                    for(l=2;l<=i+1;l++)s[l]=(l&1?'C':'A');
                    for(;l<=n;l++)s[l]='B';
                    t[m]='A';
                    for(l=m-1;l>=m-j;l--)t[l]=((m-l)&1?'C':'A');
                    for(;l>=1;l--)t[l]='B';
                    if(s[n]!='A'&&t[1]!='C'){
                        puts(s+1),puts(t+1);
                        return 0;
                    }
                }
                f[1]=(i>>1),f[2]=(j>>1),f[3]=f[1]+f[2]+1;
                if(check(3)){
                    int l;
                    s[n]='A';
                    for(l=n-1;l>=n-i;l--)s[l]=((n-l)&1?'C':'A');
                    for(;l>=1;l--)s[l]='B';
                    t[1]='C';
                    for(l=2;l<=j+1;l++)t[l]=(l&1?'C':'A');
                    for(;l<=m;l++)t[l]='B';
                    if(s[1]!='C'&&t[m]!='A'){
                        puts(s+1),puts(t+1);
                        return 0;
                    }
                }
            }
            if(i==0&&j<=m-2){
                f[1]=0,f[2]=(j>>1),f[3]=f[1]+f[2],f[4]=f[2]+f[3];
                int p=4;
                while(p<k){
                    p++;
                    f[p]=f[p-2]+f[p-1]+(p&1);
                }
                if(f[p]==x){
                    int l;
                    for(l=1;l<=n;l++)s[l]='B';
                    t[1]='C';
                    for(l=2;l<m;l++)t[l]=(l&1?'C':'A');
                    t[m]='A';
                    puts(s+1),puts(t+1);
                    return 0;
                }
            }
            if(i<=n-1&&j<=m-2){
                f[1]=(i>>1),f[2]=(j>>1),f[3]=f[1]+f[2]+1;
                if(check(5)){
                    int l;
                    s[n]='A';
                    for(l=n-1;l>=n-i;l--)s[l]=((n-l)&1?'C':'A');
                    for(;l>=1;l--)s[l]='B';
                    t[1]='C';
                    for(l=2;l<=j+1;l++)t[l]=(l&1?'C':'A');
                    for(;l<m;l++)t[l]='B';
                    t[m]='A';
                    if(s[1]!='C'){
                        puts(s+1),puts(t+1);
                        return 0;
                    }
                }
            }
            if(i<=n-2&&j<=m-2){
                f[1]=(i>>1),f[2]=(j>>1),f[3]=f[1]+f[2]+1;
                if(check(4)){
                    int l;
                    s[1]='C',s[n]='A';
                    for(l=2;l<=i+1;l++)s[l]=(l&1?'C':'A');
                    for(;l<n;l++)s[l]='B';
                    t[1]='C',t[m]='A';
                    for(l=2;l<=j+1;l++)t[l]=(l&1?'C':'A');
                    for(;l<m;l++)t[l]='B';
                    puts(s+1),puts(t+1);
                    return 0;
                }
            }
        }
    }
    puts("Happy new year!");
    return 0;
}

Code 2

#include<iostream>
#include<cstdio>
#include<algorithm>
#define int long long
#define rep(a)  for(int a=0;a<2;a++)//0 在首位表示C,在末尾表示A,1则反之
using namespace std;
int F[105];
int dp[105];
int a,b,c,p1,p2,p3;
int k,x,n,m;
signed main(){
  scanf("%lld%lld%lld%lld",&k,&x,&n,&m);
  for(int i=0;i<=n/2;i++)
  for(int r=0;r<=m/2;r++)
    rep(a)
      rep(b)
        rep(c)
          rep(d){
             if(i*2+a+b>n||r*2+c+d>m)continue;
             int cc=(b&&c),dd=(a&&d),ee=(d&&c);
             dp[1]=i,dp[2]=r,dp[3]=i+r+cc;
             for(int p=4;p<=k;p++){// 大力七维枚举
                dp[p]=dp[p-2]+dp[p-1];
                if((p%2==0)){if(dd)dp[p]++;}
                else if(ee)dp[p]++;
                }
             if(dp[k]==x){
               if(a==1)putchar('C');
               for(int p=1;p<=i;p++)putchar('A'),putchar('C');
               for(int p=i*2+a+1;p<=n-b;p++)putchar('X');
               if(b)putchar('A');
               putchar('\n');
               if(c)putchar('C');
               for(int p=1;p<=r;p++)putchar('A'),putchar('C');
               for(int p=r*2+c+1;p<=m-d;p++)putchar('X');
               if(d)putchar('A');
               putchar('\n');
               return 0;
               }
             }
  puts("Happy new year!");
  return 0;
  }

Code 3

#include<bits/stdc++.h>
#define int long long
using namespace std;
int l[500005],r[500005],t[7][500005];
signed main()
{
    int k,x,n,m;
    scanf("%lld%lld%lld%lld",&k,&x,&n,&m);
    l[1]=r[1]=1;
    l[2]=r[2]=2;
    t[3][1]=1;
    t[4][2]=1;
    for(int i=3;i<=k;i++)
    {
        t[1][i]=t[1][i-1]+t[1][i-2];//12
        t[2][i]=t[2][i-1]+t[2][i-2];//21
        t[3][i]=t[3][i-1]+t[3][i-2];//111
        t[4][i]=t[4][i-1]+t[4][i-2];//12
        t[5][i]=t[5][i-1]+t[5][i-2];//12
        if(r[i-2]==1&&l[i-1]==2) t[1][i]++;
        if(r[i-2]==2&&l[i-1]==1) t[2][i]++;
        if(r[i-2]==2&&l[i-1]==2) t[5][i]++;
        r[i]=r[i-1];
        l[i]=l[i-2];
    }
    int xx=x;
    for(int i=0;i<=n/2;i++)
    {
        int xxx=xx-t[3][k]*i;
        if(xxx<0) break;
        if(xxx%t[4][k]==0&&xxx/t[4][k]<=m/2)
        {
            for(int j=1;j<=i;j++)
            {
                printf("AC");
            }
            for(int j=i*2+1;j<=n;j++)
            {
                printf("B");
            }
            printf("\n");
            for(int j=1;j<=xxx/t[4][k];j++)
            {
                printf("AC");
            }
            for(int j=xxx/t[4][k]*2+1;j<=m;j++)
            {
                printf("B");
            }
            printf("\n");
            return 0;
        }
    }
    n--,m--;
    xx=x-t[1][k];
    for(int i=0;i<=n/2;i++)
    {
        int xxx=xx-t[3][k]*i;
        if(xxx<0) break;
        if(xxx%t[4][k]==0&&xxx/t[4][k]<=m/2)
        {
            for(int j=1;j<=i;j++)
            {
                printf("AC");
            }
            for(int j=i*2+1;j<=n;j++)
            {
                printf("B");
            }
            printf("A\nC");
            for(int j=1;j<=xxx/t[4][k];j++)
            {
                printf("AC");
            }
            for(int j=xxx/t[4][k]*2+1;j<=m;j++)
            {
                printf("B");
            }
            printf("\n");
            return 0;
        }
    }
    xx=x-t[2][k];
    for(int i=0;i<=n/2;i++)
    {
        int xxx=xx-t[3][k]*i;
        if(xxx<0) break;
        if(xxx%t[4][k]==0&&xxx/t[4][k]<=m/2)
        {
            printf("C");
            for(int j=1;j<=i;j++)
            {
                printf("AC");
            }
            for(int j=i*2+1;j<=n;j++)
            {
                printf("B");
            }
            printf("\n");
            for(int j=1;j<=xxx/t[4][k];j++)
            {
                printf("AC");
            }
            for(int j=xxx/t[4][k]*2+1;j<=m;j++)
            {
                printf("B");
            }
            printf("A\n");
            return 0;
        }
    }
    n++,m--;
    if(m>=0)
    {
        xx=x-t[5][k];
        for(int i=0;i<=n/2;i++)
        {
            int xxx=xx-t[3][k]*i;
            if(xxx<0) break;
            if(xxx%t[4][k]==0&&xxx/t[4][k]<=m/2)
            {
                for(int j=1;j<=i;j++)
                {
                    printf("AC");
                }
                for(int j=i*2+1;j<=n;j++)
                {
                    printf("B");
                }
                printf("\nC");
                for(int j=1;j<=xxx/t[4][k];j++)
                {
                    printf("AC");
                }
                for(int j=xxx/t[4][k]*2+1;j<=m;j++)
                {
                    printf("B");
                }
                printf("A\n");
                return 0;
            }
        }
    }
    n-=2;
    if(n>=0&&m>=0)
    {
        xx=x-t[1][k]-t[5][k];
        for(int i=0;i<=n/2;i++)
        {
            int xxx=xx-t[3][k]*i;
            if(xxx<0) break;
            if(xxx%t[4][k]==0&&xxx/t[4][k]<=m/2)
            {
                printf("B");
                for(int j=1;j<=i;j++)
                {
                    printf("AC");
                }
                for(int j=i*2+1;j<=n;j++)
                {
                    printf("B");
                }
                printf("A\nC");
                for(int j=1;j<=xxx/t[4][k];j++)
                {
                    printf("AC");
                }
                for(int j=xxx/t[4][k]*2+1;j<=m;j++)
                {
                    printf("B");
                }
                printf("A\n");
                return 0;
            }
        }
        xx=x-t[2][k]-t[5][k];
        for(int i=0;i<=n/2;i++)
        {
            int xxx=xx-t[3][k]*i;
            if(xxx<0) break;
            if(xxx%t[4][k]==0&&xxx/t[4][k]<=m/2)
            {
                printf("C");
                for(int j=1;j<=i;j++)
                {
                    printf("AC");
                }
                for(int j=i*2+1;j<=n;j++)
                {
                    printf("B");
                }
                printf("B\nC");
                for(int j=1;j<=xxx/t[4][k];j++)
                {
                    printf("AC");
                }
                for(int j=xxx/t[4][k]*2+1;j<=m;j++)
                {
                    printf("B");
                }
                printf("A\n");
                return 0;
            }
        }
        xx=x-t[1][k]-t[2][k]-t[5][k];
        for(int i=0;i<=n/2;i++)
        {
            int xxx=xx-t[3][k]*i;
            if(xxx<0) break;
            if(xxx%t[4][k]==0&&xxx/t[4][k]<=m/2)
            {
                printf("C");
                for(int j=1;j<=i;j++)
                {
                    printf("AC");
                }
                for(int j=i*2+1;j<=n;j++)
                {
                    printf("B");
                }
                printf("A\nC");
                for(int j=1;j<=xxx/t[4][k];j++)
                {
                    printf("AC");
                }
                for(int j=xxx/t[4][k]*2+1;j<=m;j++)
                {
                    printf("B");
                }
                printf("A\n");
                return 0;
            }
        }
    }
    printf("Happy new year!\n");
    return 0;
}

379 E

题意

\(n\) 个多边形,每个多边形有 \(k+2\) 个点
\(i\) 个点( \(2\le i\le k+1\) )的 \(x\) 坐标为 \(i-1\)
\(1\) 个点的坐标为 \((0,0)\)
\(k+2\) 个点的坐标为 \((k,0)\)
将这些多边形依次放到坐标系中,问每个多边形没有被其他多边形这遮住的部分的面积是多少。
( \(1\le n,k\le 300,误差\le 1e-4\) )

Examples

Input
2 2
2 1 2
1 2 1
Output
3.000000000000
0.500000000000
Input
1 1
1 1
Output
1.000000000000
Input
4 1
2 7
7 2
5 5
6 4
Output
4.500000000000
1.250000000000
0.050000000000
0.016666666667

解 1

用微积分思想
以一个极小的间隔暴扫对于一个\(x\)坐标能到达的最大高度,算出以该间隔为宽、高度为长的矩形面积,再减去上一次扫到的最大高度所构成的矩形的面积,与 \(0\) 取个 \(\max\) ,全部加起来即为答案。

Code 1

#include<bits/stdc++.h>
#define maxn 303
using namespace std;
double y[maxn][maxn],mx[2000003];
int n,k;
int main(){
    scanf("%d%d",&n,&k);
    int delta=1000000/k;
    for(register int i=1;i<=n;i++){
        for(register int j=0;j<=k;j++){
            scanf("%lf",&y[i][j]);
        }
        double ans=0,yy,deltay;
        for(register int j=0;j<k;j++){
            yy=y[i][j];
            deltay=(y[i][j+1]-y[i][j])/delta;
            for(register int p=j*delta+1;p<=(j+1)*delta;p++){
                yy+=deltay;
                if(yy>mx[p]){
                    ans+=yy-mx[p];
                    mx[p]=yy;
                }
            }
        }
        printf("%.12lf\n",ans/delta);
    }
    return 0;
}

解 2

把坐标系分成 \(k\) 个矩形,每个做 \(n\) 次半平面交,切掉一块,用vector维护当前多边形的顶点。
时间复杂度 \(O(nk)\)

Code 2

#include<bits/stdc++.h>
#define maxn 303
#define E 1e-8
#define INF 1e18
using namespace std;
typedef double tp;
int sgn(tp x){return x<-E?-1:x>E;}
struct point{
    tp x,y;
    point(){}
    point(tp _x,tp _y):x(_x),y(_y){}
void write(){printf("%.4lf %.4lf\n",x,y);}
    bool operator <(const point& p)const{return sgn(x-p.x)==0?sgn(y-p.y)<0:sgn(x-p.x)<0;}
    bool operator ==(const point& p)const{return sgn(x-p.x)==0&&sgn(y-p.y)==0;}
    point operator +(const point& p)const{return point(x+p.x,y+p.y);}
    point operator -(const point& p)const{return point(x-p.x,y-p.y);}
    point operator *(tp k)const{return point(x*k,y*k);}
    double norm()const{return x*x+y*y;}
};
typedef point Vec;
tp dot(const Vec& u,const Vec& v){return u.x*v.x+u.y*v.y;}
tp cross(const Vec& u,const Vec& v){return u.x*v.y-v.x*u.y;}
double dist(const point& p1,const point& p2){return sqrt(double(dot(p1-p2,p1-p2)));}

point inter(const point& P,const Vec& v,const point& Q,const Vec& w){
  Vec u=P-Q;
  if(sgn(cross(v,w))==0){
    if(sgn(cross(Q-P,v))==0)return point(-INF,-INF); //chong he
    return point(INF,INF); //ping xing
  }
  tp t=cross(w,u)/cross(v,w);
  return P+v*t; //OK
}

double getS(const vector<point>& p){
    double ans=cross(p[0],p[p.size()-1]);
    for(int i=1;i<int(p.size());i++)ans+=cross(p[i],p[i-1]);
    return abs(ans)*0.5;
}

bool onright(const point& P,const point& S,const point& T){
    return sgn(cross(T-S,P-S))<0;
}
void change(vector<point>& a,const point& p1,const point& p2){
    int l,r;
    for(l=0;l<int(a.size())&&!onright(a[l],p1,p2);l++);
    if(l>=int(a.size()))return;
    for(r=l;r<int(a.size())&&onright(a[r],p1,p2);r++);
    point a1=a[l-1],a2=a[l],a3=a[r-1],a4=a[r];
    a.erase(a.begin()+l,a.begin()+r);
    a.insert(a.begin()+l,inter(a1,a2-a1,p1,p2-p1));
    a.insert(a.begin()+l+1,inter(a3,a4-a3,p1,p2-p1));
}

point a[maxn][maxn];
vector<point> p[maxn];
double S[maxn];
int n,k;
int main(){
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
        for(int j=0;j<=k;j++)scanf("%lf",&a[i][j].y),a[i][j].x=j;
    }
    for(int j=1;j<=k;j++){
        p[j].push_back(point(j-1,1001));
        p[j].push_back(point(j-1,0));
        p[j].push_back(point(j,0));
        p[j].push_back(point(j,1001));
        S[j]=getS(p[j]);
    }
    for(int i=1;i<=n;i++){
        double res=0;
        for(int j=1;j<=k;j++){
            double last=S[j];
            change(p[j],a[i][j-1],a[i][j]);
            S[j]=getS(p[j]);
            res+=last-S[j];
        }
        printf("%.12lf\n",res);
    }
    return 0;
}
posted @ 2019-02-16 15:54  chc_1234567890  阅读(139)  评论(0编辑  收藏  举报