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时的每加一瓶所要加的伤害值预处理出来
然后一次求前缀和
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
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
代码;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
本文来自博客园,作者:键盘侠牧师,转载请注明原文链接:https://www.cnblogs.com/wangzhe52xia/p/11899762.html