2 条题解

  • 0
    @ 2026-9-2 10:57:20

    贪心部分:

    对于第 ii个大臣和第 jj 个大臣:

    如果第 ii 个大臣放第 jj 个大臣前面对答案的贡献小些,那么第 ii 个大臣就放第 jj 个大臣前面

    所以就是使 a[i].x/a[j].y<a[j].x/a[i].ya[i].x/a[j].y<a[j].x/a[i].y

    所以就是a[i].xa[i].y<a[j].xa[j].ya[i].x*a[i].y<a[j].x*a[j].y

    然后高精度部分压位,这样快得多,20ms,

    乘法部分相当于高精度乘低精度

    除法部分相当于高精度除低精度

    #include<bits/stdc++.h>
    using namespace std;
    int read()
    {
        char s;
        int k=0,base=1;
        while((s=getchar())!='-'&&s!=EOF&&!(s>='0'&&s<='9'));
        if(s==EOF)exit(0);
        if(s=='-')base=-1,s=getchar();
        while(s>='0'&&s<='9')
        {
            k=k*10+(s-'0');
            s=getchar();
        }
        return k*base;
    }
    void write(int x)
    {
        if(x<0)
        {
            putchar('-');
            write(-x);
        }
        else
        {
            if(x/10)write(x/10);
            putchar(x%10+'0');
        }
    }
    int n,A,B;
    struct node
    {
        int x,y;
    } a[1010];
    bool cmp(node aa,node bb)
    {
        if (aa.x*aa.y==bb.x*bb.y) return aa.y<bb.y;
        return (aa.x*aa.y)<(bb.x*bb.y);
    }
    int sum[1010];
    int ans[1010],ls;
    int p[1010],lp;
    int m;//sum长度
    int P;
    bool Max()//比大小,ans>p: true
    {
        int i=1;
        while (p[i]==0&&i<=lp) i++;//去掉前面的0
        int j=1;
        while (ans[j]==0&&j<=ls) j++;
        if (lp-i+1>ls-j+1) return false;//p的位数>ans的位数
        if (lp-i+1<ls-j+1) return true;
        while (i<=lp&&j<=ls)//一位一位的比较
        {
            if (p[i]<ans[j]) return true;
            if (p[i]>ans[j]) return false;
            i++;
            j++;
        }
        return false;
    }
    void cheng(int d)
    {
        for (int i=1;i<=m;i++)
            sum[i]*=a[d].x;//高精度乘法
        for (int i=1;i<=m;i++)//进位
        {
            sum[i+1]+=sum[i]/10000;
            sum[i]%=10000;
        }
        if (sum[m+1]!=0) m++;
    }
    void div(int d)
    {
        memset(ans,0,sizeof(ans));
        ls=1;
        while (m>0&&sum[m]==0) m--;//去掉前导0
        P=0;
        int flag=0;
        for (int i=m;i>=1;i--)//高精度除法(模拟竖式)
        {
            P=P*10000+sum[i];
            ans[++ls]=P/a[d].y;
            if (ans[ls]==0&&!flag) ls--; else flag=1;
            P%=a[d].y;
        }
    }
    int main()
    {
        n=read();
        A=read();
        B=read();
        for (int i=1;i<=n;i++) a[i].x=read(),a[i].y=read();
        sort(a+1,a+n+1,cmp);
        m=1;
        sum[1]=A;
        for (int i=1;i<=n;i++)
        {
            div(i);
            if (Max())
            {
                lp=ls;
                memcpy(p,ans,sizeof(ans));
            }
            cheng(i);
        }
        int i=0;
        while (i<=lp&&p[i]==0) i++;
        printf("%d",p[i]);i++;
        for (;i<=lp;i++)//输出
        {
            if (0<=p[i]&&p[i]<=9) printf("000%d",p[i]);else
            if (10<=p[i]&&p[i]<=99) printf("00%d",p[i]);else
            if (100<=p[i]&&p[i]<=999) printf("0%d",p[i]);else
            printf("%d",p[i]);
        }
        return 0;
    }
    
    • 0
      @ 2025-10-8 16:55:59
      #include <bits/stdc++.h>
      using namespace std;
      struct node{int x,y;}a[1100];
      bool cmp(node n1,node n2) {return n1.x*n1.y < n2.x*n2.y;}
      
      struct Num
      {
          int a[5100],len;
          Num(){ len=1;memset(a,0,sizeof(a));}
      };
      bool compare(Num n1,Num n2)
      {
          if(n1.len < n2.len) return false;
          if(n1.len > n2.len) return true;
          for(int i=n1.len;i>=1;i--)
          {
              if(n1.a[i] > n2.a[i]) return true;
              if(n1.a[i] < n2.a[i]) return false;
          }
          return false;
      }
      Num operator /(Num n1,int x)
      {
          Num no;no.len=n1.len;int t=0;
          for(int i=n1.len;i>=1;i--)
          {
              t=t*10+n1.a[i];
              no.a[i]=t/x;
              t%=x;
          } 
          while(no.a[no.len]==0 && no.len>1) no.len--;
          if(no.len==0)no.len=1;
          return no;
      }
      Num operator *(Num n1,int x)
      {
          Num no;no.len=n1.len;
          for(int i=1;i<=no.len;i++) no.a[i]=n1.a[i]*x;
          for(int i=1;i<=no.len;i++) 
              no.a[i+1]+=no.a[i]/10,no.a[i]%=10;
          int i=no.len;
          while(no.a[i+1]>0) i++,no.a[i+1]+=no.a[i]/10,no.a[i]%=10;
          while(no.a[i]==0 && i>1 )i--;
          no.len=i;
          return no;
      }
      int main()
      {
          int n;scanf("%d", &n);
          for(int i=0;i<=n;i++) scanf("%d%d", &a[i].x, &a[i].y);
          sort(a+1,a+n+1,cmp);
          Num sum, ans;
          memset(ans.a,0,sizeof(ans.a));ans.len=1;
          sum.a[1]=1;sum.len=1;
          for(int i=1;i<=n;i++)
          {
              sum=sum*a[i-1].x;
              Num t=sum/a[i].y;
              if(compare(t,ans))
              {
                  ans=t;
              }
          }
          for(int i=ans.len;i>=1;i--) printf("%d",ans.a[i]);
          return 0;
      }
      
      • 1

      A32 贪心算法 [NOIP2012 提高组] 国王游戏

      信息

      ID
      1138
      时间
      1000ms
      内存
      128MiB
      难度
      5
      标签
      递交数
      122
      已通过
      44
      上传者