码迷,mamicode.com
首页 > 其他好文 > 详细

n诺挑战赛5题解

时间:2019-11-20 19:50:55      阅读:86      评论:0      收藏:0      [点我收藏+]

标签:scanf   printf   spl   void   include   自己   快速   show   图片   

Drinking

题意:就是给你n瓶酒的初始伤害值,第几天喝这瓶酒伤害值就是这瓶酒的初始伤害值第几倍,而且他每天喝的瓶数不超过m。要你输出所有的情况,就是他喝(1~n)瓶的伤害值的最小,

思路:就是这些酒从小到大排序,越小的越往后退,这就相当于是一个火车,每一个车厢只能装m个人,每往后座一节车厢,自己的票价就要多加一次,

当酒瓶数没有超过m时,就是第一天可以吃完的,不就是酒瓶从小到大的前缀和吗?

当大于m时,例如当酒瓶数k = m +1 时,第一瓶酒被挤到了第二天去吃,第m+1块酒瓶要第一天吃,不就是吃m瓶酒在上第一一瓶酒和第m+1瓶酒吗?

因为是m瓶一循环,所以当瓶数p大于m时,与p-1瓶时相比所有(p%m)的倍数都往后推了一天,也就是伤害值增加了(a[p%m], a[p%m+m].....a[p-m]},同时a[p]也增加进来了

 

因此我们要先把大于m时的每加一瓶所要加的伤害值预处理出来

然后一次求前缀和

 

 

技术图片
 1 #include <iostream>
 2 #include <cmath>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <cstring>
 6 #include <string>
 7 #include <vector>
 8 #include <set>
 9 #include <map>
10 #include <queue>
11 
12 using namespace std;
13 const int N = 2e5 +10;
14 typedef long long ll;
15 ll a[N],ans[N],b[N];
16 int main()
17 {
18     int n,m;
19     cin >> n >> m;
20     for(int i = 1 ; i <= n; i ++)
21     {
22         scanf("%d",&a[i]);
23     }
24     sort(a+1,a+n+1);
25     for(int j = m + 1; j <= n; j++ )
26     {
27         b[j] = b[j-m] + a[j-m];//预处理第j天比(j-1)天要多加的伤害值
28         //第j天我们要把所有(j%m)的倍数中小于j的都加一次
29     }
30     for(int i=1;i<=n;i++)
31     {
32         a[i]=a[i-1]+a[i] + b[i];
33         //b[i]表示第i天除了由第0天变道第一天的其他所有添加的伤害值
34         printf("%lld ",a[i]);
35     }
36     return 0;
37 }
View Code

 


River‘s lake

题意:a[1]=1,a[2]=3,...a[n]=a[n-1]*3 + a[n-2]*2;,这是一个矩阵快速幂的裸体,而且已经给出了状态转移矩阵,但是这个题有一个坑点就是这个斐波那契数列不是从零开始的而是从一开始的,因此n要先减去一个1

 

代码:

#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int Mod = 1e5;
void mul(int f[2],int a[2][2])
{
    int c[2];
    memset(c,0,sizeof(c));
    for(int i=0;i<2;i++)
    {
        for(int j=0;j<2;j++)
        {
            c[i]= (c[i] + (ll)f[j]*a[j][i])%Mod ;
        }
    }
    memcpy(f,c,sizeof(c));
}
void mulself(int a[2][2])
{
    int c[2][2];
    memset(c,0,sizeof(c));
    for(int i=0;i<2;i++)
    {
        for(int j=0;j<2;j++)
        {
            for(int k =0;k<2;k++)
            {
                c[i][j] = (c[i][j] + (ll) a[i][k]*a[k][j])%Mod;
            }
        }
    }
    memcpy(a,c,sizeof(c));
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        n--;
        int f[2]={1,3};
        int a[2][2]={{0,2},{1,3}};
        while(n)
        {
            if(n&1)mul(f,a);
            mulself(a);
            n>>=1;
        }
        cout << f[0]<<endl;
    }
}

 

 

 

Weapons

 

题意:给你一个y,n,k;求出所有(x+y)|k且(x>0,y>0)(x+y<=n)

按照升序输出所有的x

 

代码;

技术图片
 1 #include <iostream>
 2 #include <bits/stdc++.h>
 3 
 4 using namespace std;
 5 typedef long long ll;
 6 int main()
 7 {
 8     int y,n,k,i;
 9     scanf("%d %d %d",&y,&k,&n);
10     for(i=(y/k+1)*k;i<=n;i+=k)
11     {
12         printf("%d ",i-y);
13     }
14     if((y/k+1)*k>n)
15     {
16         printf("-1");
17     }
18     return 0;
19 }
View Code

 

 

 

n诺挑战赛5题解

标签:scanf   printf   spl   void   include   自己   快速   show   图片   

原文地址:https://www.cnblogs.com/wangzhe52xia/p/11899762.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!