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 }
  • 相关阅读:
    POJ3693 Maximum repetition substring —— 后缀数组 重复次数最多的连续重复子串
    SPOJ
    POJ2774 Long Long Message —— 后缀数组 两字符串的最长公共子串
    POJ3261 Milk Patterns —— 后缀数组 出现k次且可重叠的最长子串
    POJ1743 Musical Theme —— 后缀数组 重复出现且不重叠的最长子串
    SPOJ
    AC自动机小结
    HDU3247 Resource Archiver —— AC自动机 + BFS最短路 + 状压DP
    POJ1625 Censored! —— AC自动机 + DP + 大数
    Herding
  • 原文地址:https://www.cnblogs.com/Var123/p/5374553.html
Copyright © 2011-2022 走看看