zoukankan      html  css  js  c++  java
  • Tsinsen A1504. Book(王迪) 数论,贪心

    A1504. Book(王迪)
    时间限制:1.0s   内存限制:256.0MB   Special Judge
    总提交次数:359   AC次数:97   平均分:43.76
     
    将本题分享到:
          
       
    试题来源
      2013中国国家集训队第二次作业
    问题描述
      Wayne喜欢看书,更喜欢买书。
      某天Wayne在当当网上买书,买了很多很多书。Wayne有一个奇怪的癖好,就是第一本书的价格必须恰为X,而之后买的每一本书,若是比上一本更昂贵,则价格最多多A元;若是比上一本更便宜,则价格最多少B元。
      Wayne心血来潮,一口气买了N本书,但他记不得每本书的价格了,只记得总价格是M。Wayne于是很想知道一种可能的书价分布。为了简化问题,我们假定书价的定义域是整数,且每本书与上一本书的价格差,要么恰为+A,要么恰为-B。
      只要给出任意一个合法的书价序列就算正确。
    输入格式
      第一行一个正整数N。
      第二行四个整数依次是X,A,B,M。
    输出格式
      输出一行N个整数,用空格隔开。数据保证有解。
    样例输入
    4
    10 1 2 37
    样例输出
    10 11 9 7
    数据规模和约定
      对于5%的数据,满足N = 1。
      对于另外25%的数据,满足A = B = 1, N <= 100。
      对于另外10%的数据,满足A, B <= 5, N <= 100。
      对于另外20%的数据,满足N <= 1000。
      对于100%的数据,满足1 <= A, B <= 10^6,|X| <= 10^6,N <= 10^5,M可用带符号64位整型存储。
     
     
    题解:
    数论+贪心
    以下是王迪的解题报告:
     
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define LL long long
     4 //LL prey[100010];
     5 bool vis[100010];
     6 LL read()
     7 {
     8     LL s=0,fh=1;char ch=getchar();
     9     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
    10     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
    11     return s*fh;
    12 }
    13 int main()
    14 {
    15     LL n,x,a,b,m,k,i,j,lp;
    16     n=read();
    17     x=read();a=read();b=read();m=read();
    18     k=n*x+((n-1)*n)/2*a;//假设全部增加a的总钱数.
    19     k-=m;//用 全部增加a的总钱数 减去 实际花费的钱数 得到有多少钱从 +a 转化为 -b ,也就是减去(a+b).
    20     k/=(a+b);//计算出有多少书进行了从 +a 转化为 -b.
    21     //因为改变每一个差量,所影响的数的个数为(0,1,2...n-1)中的一个.所以,我们只需要求出k可以由 0~(n-1) 中的哪一些组成.
    22     memset(vis,false,sizeof(vis));
    23     for(i=n-1;i>=0;i--)//倒着去找,一定保证k可以组成.(有点类似倍增LCA的倒着找的原理)
    24     {
    25         if(k>=i)
    26         {
    27             k-=i;
    28             vis[i]=true;//标记为true的代表要转换为-b.
    29             if(k==0)break;
    30         }
    31     }
    32     /*双重循环(60分)
    33     for(i=1;i<=n;i++){prey[i]=x;x+=a;}
    34     for(i=1;i<=n-1;i++)
    35     {
    36         if(vis[i]==true)
    37         {
    38             for(j=n;j>=n-i+1;j--)prey[j]-=(a+b);
    39         }
    40     }
    41     for(i=1;i<=n;i++)printf("%lld ",prey[i]);*/
    42     printf("%lld",x);
    43     for(i=n-1;i>=1;i--)
    44     {
    45         if(vis[i]==true)//若要转化为-b,就要在原先的x的基础上加上-b(即减去b).
    46         {
    47             x-=b;
    48         }
    49         else
    50         {
    51             x+=a;
    52         }
    53         printf(" %lld",x);
    54     }
    55     fclose(stdin);
    56     fclose(stdout);
    57     return 0;
    58 }
  • 相关阅读:
    C语言C++编程学习:排序原理分析
    Ubuntu下开机进程管理工具sysvrcconf
    康托展开
    USACO 3.2 Magic Squares题解
    『转』ubuntu的电池管理
    poj1061青蛙的约会解题报告
    Dancing Links
    【转】史上最强vim配置文件vimrc
    四柱汉诺塔
    又遇欧拉 转载之
  • 原文地址:https://www.cnblogs.com/Var123/p/5374553.html
Copyright © 2011-2022 走看看