• NOIP2015 pj


    达成成就!——尝试不看题解的情况下用cpp打完了一套NOIP pj

    题目全部在luogu上——

    P2669 金币

    题目描述

    国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去:当连续N天每天收到N枚金币后,骑士会在之后的连续N+1天里,每天收到N+1枚金币。

    请计算在前K天里,骑士一共获得了多少金币。

    输入输出格式

    输入格式:

    输入文件只有1行,包含一个正整数K,表示发放金币的天数。

    输出格式:

    输出文件只有1行,包含一个正整数,即骑士收到的金币数。

    输入输出样例

    输入样例#1:
    6
    输出样例#1:
    14
    输入样例#2:
    1000
    
    输出样例#2:
    29820
    

    说明

    【输入输出样例 1 说明】

    骑士第一天收到一枚金币;第二天和第三天,每天收到两枚金币;第四、五、六天,

    每天收到三枚金币。因此一共收到 1+2+2+3+3+3=14 枚金币。

    对于 100%的数据, 1 ≤ K ≤ 10,000。

    Solution

    直接模拟

     1 #include<cstdio>
     2 using namespace std;
     3 
     4 int main(){
     5   //freopen("1.in","r",stdin);
     6   //freopen("1.out","w",stdout);
     7 
     8   int n;
     9   int i=0;
    10   int ans=0;
    11 
    12   scanf("%d",&n);
    13 
    14   while (n>0)
    15   {
    16     n-=++i;
    17     ans=ans+i*i;
    18   }
    19 
    20   ans=ans-(0-n)*i;
    21   printf("%d",ans);
    22 
    23   fclose(stdin);  fclose(stdout);
    24   return 0;
    25 }
    View Code

    P2670 扫雷游戏

    题目描述

    扫雷游戏是一款十分经典的单机小游戏。在n行m列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格。

    现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格周围的地雷格数。

    注:一个格子的周围格子包括其上、下、左、右、左上、右上、左下、右下八个方向上与之直接相邻的格子。

    输入输出格式

    输入格式:

    输入文件第一行是用一个空格隔开的两个整数n和m,分别表示雷区的行数和列数。

    接下来n行,每行m个字符,描述了雷区中的地雷分布情况。字符’*’表示相应格子是地雷格,字符’?’表示相应格子是非地雷格。相邻字符之间无分隔符。

    输出格式:

    输出文件包含n行,每行m个字符,描述整个雷区。用’*’表示地雷格,用周围的地雷个数表示非地雷格。相邻字符之间无分隔符。

    输入输出样例

    输入样例#1:
    3 3
    *??
    ???
    ?*?
    
    输出样例#1:
    *10
    221
    1*1
    输入样例#2:
    2 3
    ?*?
    *??
    输出样例#2:
    2*1
    *21

    说明

    对于 100%的数据, 1≤n≤100, 1≤m≤100。

    Solution

    还是模拟。。。

     1 #include<cstdio>
     2 #include<cstring>
     3 using namespace std;
     4 int main(){
     5   char c[100][100];
     6   int apple[102][102];
     7   memset(apple,0,sizeof(apple));
     8   freopen("1.in","r",stdin);
     9   freopen("1.out","w",stdout);
    10 
    11   int n,m;
    12   scanf("%d %d
    ",&n,&m);
    13 
    14   for (int i=1;i<=n;i++){
    15    for (int j=1;j<=m;j++)
    16    {
    17     scanf("%c",&c[i][j]);
    18     if (c[i][j]=='*'){
    19       apple[i-1][j-1]++;
    20       apple[i+1][j+1]++;
    21       apple[i][j-1]++;
    22       apple[i-1][j]++;
    23       apple[i][j+1]++;
    24       apple[i+1][j]++;
    25       apple[i-1][j+1]++;
    26       apple[i+1][j-1]++;
    27     }
    28     }
    29     scanf("
    ");
    30    }
    31   for (int i=1;i<=n;i++)
    32   {
    33     for (int j=1; j<=m;j++){
    34     if (c[i][j]=='?') printf("%d",apple[i][j]);
    35       else printf("*");
    36     }
    37     printf("
    ");
    38   }
    39 
    40 }
    View Code

    P2671 求和

    题目描述

    一条狭长的纸带被均匀划分出了n个格子,格子编号从1到n。每个格子上都染了一种颜色color_i用[1,m]当中的一个整数表示),并且写了一个数字number_i。

    定义一种特殊的三元组:(x,y,z),其中x,y,z都代表纸带上格子的编号,这里的三元

    组要求满足以下两个条件:

    1.xyz是整数,x<y<z,y-x=z-y

    2.colorx=colorz

    满足上述条件的三元组的分数规定为(x+z)*(number_x+number_z。整个纸带的分数

    规定为所有满足条件的三元组的分数的和。这个分数可能会很大,你只要输出整个纸带的分数除以10,007所得的余数即可。

    输入输出格式

    输入格式:

    第一行是用一个空格隔开的两个正整数n和m,n表纸带上格子的个数,m表纸带上颜色的种类数。

    第二行有n用空格隔开的正整数,第i数字number表纸带上编号为i格子上面写的数字。

    第三行有n用空格隔开的正整数,第i数字color表纸带上编号为i格子染的颜色。

    输出格式:

    共一行,一个整数,表示所求的纸带分数除以10,007所得的余数。

    输入输出样例

    输入样例#1:
    6 2
    5 5 3 2 2 2
    2 2 1 1 2 1
    输出样例#1:
    82
    
    输入样例#2:
    15 4
    5 10 8 2 2 2 9 9 7 7 5 6 4 2 4
    2 2 3 3 4 3 3 2 4 4 4 4 1 1 1
    输出样例#2:
    1388

    说明

    【输入输出样例 1 说明】

    纸带如题目描述中的图所示。

    所有满足条件的三元组为: (1, 3, 5), (4, 5, 6)。

    所以纸带的分数为(1 + 5)*(5 + 2) + (4 + 6)*(2 + 2) = 42 + 40 = 82。

    对于第 1 组至第 2 组数据, 1 ≤ n ≤ 100, 1 ≤ m ≤ 5;

    对于第 3 组至第 4 组数据, 1 ≤ n ≤ 3000, 1 ≤ m ≤ 100;

    对于第 5 组至第 6 组数据, 1 ≤ n ≤ 100000, 1 ≤ m ≤ 100000,且不存在出现次数

    超过 20 的颜色;

    对 于 全 部 10 组 数 据 , 1 ≤ n ≤ 100000, 1 ≤ m ≤ 100000, 1 ≤ color_i ≤ m,1≤number_i≤100000

    Solution

    先按颜色排序,把同颜色的归为一类,然后根据奇偶性瞎搞就可以了,取模打错了好多次。。。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 
     6 long long n,m;
     7 long long color[100001],num[100001],id[100001];
     8 const long long moding=10007;
     9 
    10 void swap(long long &aa,long long &bb){  //swap function
    11  long long tt;
    12   tt=aa;
    13   aa=bb;
    14   bb=tt;
    15 }
    16 
    17 void qsort(long long l,long long r){
    18  long long i=l,j=r,mi=id[(l+r)/2];
    19  long long  mm=color[(l+r)/2];
    20 
    21   do
    22   {
    23     while ((color[i]<mm)||(color[i]==mm&&id[i]<mi)) i++;
    24     while ((color[j]>mm)||(color[j]==mm&&mi<id[j])) j--;  //double keys qsort
    25     if (i<=j){
    26       swap(color[i],color[j]);
    27       swap(num[i],num[j]);
    28       swap(id[i],id[j]);
    29       i++;j--;
    30     }
    31   }while (i<=j);
    32 
    33   if (l<j) qsort(l,j);
    34   if (i<r) qsort(i,r);
    35 }
    36 
    37 int partit(long long  l,long long r){
    38   // long long odd_num[100001],no_num[100001];
    39  //  long long odd_color[100001],no_color[100001];
    40   long long odd=0,no=0,odd_sum=0,no_sum=0,tmp=0;
    41 
    42    for (long long j=l;j<=r;j++)
    43     if (id[j]%2==1) {
    44        odd++;
    45     odd_sum+=id[j];
    46     //    odd_num[odd]=num[j];   odd_color[odd]=color[j];
    47     }
    48     else {
    49        no++;
    50        no_sum+=id[j];
    51    //    no_num[no]=num[j];    no_color[no]=color[j];
    52     }
    53     for (long long j=l;j<=r;j++)
    54     if (id[j]%2==1) {
    55         if (odd>1)  tmp=((tmp % moding)+(num[j]*(odd_sum+id[j]*(odd-2)))%moding)%moding;
    56       //  printf("%lld 
    ",tmp);    printf("----
    ");
    57     }
    58     else if (no>1)  tmp=((tmp % moding)+(num[j]*(no_sum+id[j]*(no-2)))%moding)%moding;
    59 //  printf("%lld 
    ",tmp);  printf("======
    ");
    60    return tmp % moding;
    61 }
    62 int main(){
    63   long long ll=1,ans=0;
    64 
    65   freopen("sum.in","r",stdin);
    66   freopen("sum.out","w",stdout);
    67 
    68   scanf("%lld %lld
    ",&n,&m);
    69   for (long long i=1;i<=n;i++) scanf("%lld ",&num[i]);
    70   for (long long i=1;i<=n;i++) scanf("%lld ",&color[i]);
    71   for (long long i=1;i<=n;i++) id[i]=i;
    72       
    73   qsort(1,n);
    74 
    75   for (long long i=2;i<=n+1;i++)
    76      if (color[i]!=color[i-1])
    77      {
    78          ans=((ans % moding)+partit(ll,i-1))%moding;
    79          ll=i;
    80      }
    81   printf("%lld",ans);
    82   return 0;
    83 }
    View Code

    P2672 推销员

    题目描述

    阿明是一名推销员,他奉命到螺丝街推销他们公司的产品。螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户。螺丝街一共有N家住户,第i家住户到入口的距离为Si米。由于同一栋房子里可以有多家住户,所以可能有多家住户与入口的距离相等。阿明会从入口进入,依次向螺丝街的X家住户推销产品,然后再原路走出去。

    阿明每走1米就会积累1点疲劳值,向第i家住户推销产品会积累Ai点疲劳值。阿明是工作狂,他想知道,对于不同的X,在不走多余的路的前提下,他最多可以积累多少点疲劳值。

    输入输出格式

    输入格式:

    第一行有一个正整数N,表示螺丝街住户的数量。

    接下来的一行有N个正整数,其中第i个整数Si表示第i家住户到入口的距离。数据保证S1≤S2≤…≤Sn<10^8。

    接下来的一行有N个正整数,其中第i个整数Ai表示向第i户住户推销产品会积累的疲劳值。数据保证Ai<10^3。

    输出格式:

    输出N行,每行一个正整数,第i行整数表示当X=i时,阿明最多积累的疲劳值。

    输入输出样例

    输入样例#1:
    5
    1 2 3 4 5
    1 2 3 4 5
    输出样例#1:
    15
    19
    22
    24
    25
    输入样例#2:
    5
    1 2 2 4 5
    5 4 3 4 1
    输出样例#2:
    12
    17
    21
    24
    27

    说明

    【输入输出样例1说明】

    X=1:向住户5推销,往返走路的疲劳值为5+5,推销的疲劳值为5,总疲劳值为15。

    X=2:向住户4、5推销,往返走路的疲劳值为5+5,推销的疲劳值为4+5,总疲劳值为5+5+4+5=19。

    X=3:向住户3、4、5推销,往返走路的疲劳值为5+5,推销的疲劳值3+4+5,总疲劳值为5+5+3+4+5=22。

    X=4:向住户2、3、4、5推销,往返走路的疲劳值为5+5,推销的疲劳值2+3+4+5,总疲劳值5+5+2+3+4+5=24。

    X=5:向住户1、2、3、4、5推销,往返走路的疲劳值为5+5,推销的疲劳值1+2+3+4+5,总疲劳值5+5+1+2+3+4+5=25。

    【输入输出样例2说明】

    X=1:向住户4推销,往返走路的疲劳值为4+4,推销的疲劳值为4,总疲劳值4+4+4=12。

    X=2:向住户1、4推销,往返走路的疲劳值为4+4,推销的疲劳值为5+4,总疲劳值4+4+5+4=17。

    X=3:向住户1、2、4推销,往返走路的疲劳值为4+4,推销的疲劳值为5+4+4,总疲劳值4+4+5+4+4=21。

    X=4:向住户1、2、3、4推销,往返走路的疲劳值为4+4,推销的疲劳值为5+4+3+4,总疲劳值4+4+5+4+3+4=24。或者向住户1、2、4、5推销,往返走路的疲劳值为5+5,推销的疲劳值为5+4+4+1,总疲劳值5+5+5+4+4+1=24。

    X=5:向住户1、2、3、4、5推销,往返走路的疲劳值为5+5,推销的疲劳值为5+4+3+4+1,

    总疲劳值5+5+5+4+3+4+1=27。

    【数据说明】

    对于20%的数据,1≤N≤20;

    对于40%的数据,1≤N≤100;

    对于60%的数据,1≤N≤1000;

    对于100%的数据,1≤N≤100000。

    Solution

    刚开始测了一下二维的暴力只拿了40;

    于是开始各种奇怪的东西,=>

    首先我们可以发现在找x个买家时,我们可以从x-1的推过来,于是很明显的阶段性,决策有已经走了的和后面的,这里来个堆维护最大值就可以了,

    但是我作死维护了两棵线段树。。。。。

    然后还学会了gdb。。。。

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #define ll long long
      5 #define pr(a) for(long long i=1;i<=n;i++) printf("%lld ",a[i]);printf("
    ");
      6 const ll maxn=100000+2;
      7 using namespace std;
      8 
      9 
     10 typedef struct {
     11     ll val,left,right;
     12 }arr;
     13 
     14 //define var =====================
     15 
     16 ll n,ap;
     17 arr tree[4*maxn-1],tree2[4*maxn-1];
     18 ll dis[maxn],tir[maxn],diss[maxn];
     19 bool check[maxn];
     20 
     21 //main codes =====================
     22 
     23 void swap(long long &aa,long long &bb){  //swap function
     24  long long tt;
     25   tt=aa;
     26   aa=bb;
     27   bb=tt;
     28 }
     29 
     30 void qsort(long long l,long long r){
     31  long long i=l,j=r;
     32  long long  mm=dis[(l+r)/2];
     33 
     34   do
     35   {
     36     while (dis[i]<mm) i++;
     37     while (dis[j]>mm) j--;  //double keys qsort
     38     if (i<=j){
     39       swap(dis[i],dis[j]);
     40       swap(tir[i],tir[j]);
     41       i++;j--;
     42     }
     43   }while (i<=j);
     44 
     45   if (l<j) qsort(l,j);
     46   if (i<r) qsort(i,r);
     47 }
     48 
     49 
     50 void init(){
     51     //freopen("1.in","r",stdin);
     52    // freopen("1.out","w",stdout);
     53 
     54     memset(check,1,sizeof(check));
     55     scanf("%lld",&n);
     56 
     57     for (ll i=1;i<=n;i++) scanf("%lld ",&dis[i]);
     58     for (ll i=1;i<=n;i++) scanf("%lld ",&tir[i]);
     59 
     60     tir[0]=0;  dis[0]=0;
     61     qsort(1,n);
     62 }
     63 
     64 void build( ll l , ll r , ll w){
     65    
     66    tree[w].left=l;   tree[w].right=r;
     67    ll mid=(l+r)/2;
     68    
     69    if (l==r) {
     70                  tree[w].val=l;
     71                  return;
     72                }
     73 
     74    build(l,mid,2*w);
     75 
     76    build(mid+1,r,2*w+1);
     77 
     78    if (dis[tree[2*w].val]>dis[tree[2*w+1].val]) 
     79        tree[w].val= tree[2*w].val;
     80    else 
     81        tree[w].val= tree[2*w+1].val;
     82 
     83 }
     84 
     85 ll query( ll l , ll r , ll w){
     86 
     87    if (l<=tree[w].left&&tree[w].right<=r) return tree[w].val;
     88 
     89    ll t1=0,t2=0;
     90 
     91    if (l<=tree[2*w].right) t1=query(l,r,2*w);
     92    if (tree[2*w+1].left<=r) t2=query(l,r,2*w+1);
     93    if (dis[t1]>dis[t2]) return t1;
     94    if (dis[t1]==dis[t2]) return min(t1,t2);
     95      else return t2;
     96 }
     97 
     98 
     99 
    100 void build2( ll l , ll r , ll w){
    101    
    102    tree2[w].left=l;   tree2[w].right=r;
    103    ll mid=(l+r)/2;
    104    
    105    if (l==r) {
    106                  tree2[w].val=l;
    107                  return;
    108                }
    109 
    110    build2(l,mid,2*w);
    111 
    112    build2(mid+1,r,2*w+1);
    113 
    114    if (tir[tree2[2*w].val]>tir[tree2[2*w+1].val]) 
    115        tree2[w].val= tree2[2*w].val;
    116    else 
    117        tree2[w].val= tree2[2*w+1].val;
    118 
    119 }
    120 
    121 ll query2( ll l , ll r , ll w){
    122 
    123    if (l<=tree2[w].left&&tree2[w].right<=r) return tree2[w].val;
    124 
    125    ll t1=0,t2=0;
    126    
    127    if (l<=tree2[2*w].right) t1=query2(l,r,2*w);
    128    if (tree2[2*w+1].left<=r) t2=query2(l,r,2*w+1);
    129   
    130    if (tir[t1]>tir[t2]) return t1;
    131    if (tir[t1]==tir[t2]) return min(t1,t2);
    132      else return t2;
    133 }
    134 
    135 void update2( ll x, ll w){
    136 
    137     if (x==tree2[w].left&&x==tree2[w].right) {
    138                               tree2[w].val=0; 
    139                               return;
    140                           }
    141    if (x<=tree2[2*w].right) update2(x,2*w);
    142         else  update2(x,2*w+1);
    143        
    144    if (tir[tree2[2*w].val]>tir[tree2[2*w+1].val]) 
    145        tree2[w].val= tree2[2*w].val;
    146    else 
    147        tree2[w].val= tree2[2*w+1].val;  
    148 }
    149 void update( ll x, ll w){
    150 
    151     if (x==tree[w].left&&x==tree[w].right) {
    152                               tree[w].val=0; 
    153                               return;
    154                           }
    155    if (x<=tree[2*w].right) update(x,2*w);
    156         else  update(x,2*w+1);
    157        
    158    if (dis[tree[2*w].val]>dis[tree[2*w+1].val]) 
    159        tree[w].val= tree[2*w].val;
    160    else 
    161        tree[w].val= tree[2*w+1].val;  
    162 }
    163 
    164 int main(){
    165 
    166      init();
    167 
    168      memcpy(diss,dis,sizeof(dis));
    169      for (ll i=1;i<=n;i++)
    170          dis[i]=dis[i]*2+tir[i]; 
    171      build(1,n,1);
    172      build2(1,n,1);
    173     
    174     ll last=query(1,n,1),php1,php2;
    175     ll ans=dis[last];
    176     update(last,1);
    177     update2(last,1);
    178   //  printf("last=%lld ans=%lld
    ",last,ans);
    179     printf("%lld
    ",ans);
    180     for (ll i=2;i<=n;i++)
    181     {
    182         ap=i;
    183         php1=query2(1,last-1,1);
    184         if (last+1<=n)php2=query(last+1,n,1); else php2=0;
    185      //   printf("%lld %lld 
    ",dis[php2],last);
    186         if (tir[php1]>dis[php2]-diss[last]*2) {
    187           ans+=tir[php1];
    188          update2(php1,1);update(php1,1);
    189             }
    190         else {
    191           ans+=dis[php2]-diss[last]*2;
    192           last=php2;
    193           update(php2,1);
    194           update2(php2,1);
    195         }
    196   //   printf("last=%lld ans=%lld
    ",last,ans);
    197     printf("%lld
    ",ans);
    198    }
    199    // printf("%lld 
    ",tir[0]);
    200    return 0;
    201     
    202  }
    View Code
  • 相关阅读:
    快速幂取模
    程序人生系列之新闻发布系统 0105
    JavaWeb之博客系统(四)
    [转]树状数组
    题目:免费午餐
    题目:删数问题
    题目:三元组
    题目:分子团
    题目:[汪老师结婚]婚礼上的袭击
    题目:[SBN号码]
  • 原文地址:https://www.cnblogs.com/bobble/p/7153229.html
Copyright © 2020-2023  润新知