2013NOIP普级组-- 小朋友的数字
生活随笔
收集整理的這篇文章主要介紹了
2013NOIP普级组-- 小朋友的数字
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:
https://www.luogu.org/problemnew/show/P1982
? ? ?? 很顯然,這是一個最大字段和問題,但是要注意的是在算每個小朋友的分數的時候是會爆longlong的,我們注意到小朋友的特征值和分數是遞增的,手動進行模擬特征值和分數可以得出:
? ? ? 如果要求的小朋友的分數的上一個小朋友的特征值是大于等于零的,那么往后的時候每一個小朋友的分數都為他上一個小朋友的分數加上特征值。否則的話,這個小朋友的分數為第一個小朋友的分數加上特征值。
? ? ? 所以答案要么是第一個小朋友的分數,要么是最后一個小朋友的分數,我們最后只要對比第一個小朋友的分數和最后一個小朋友的分數就行,但是問題來了,因為分數的大小有可能會爆longlong,所以我們在計算的時候會一邊取模一邊計算,如此這般的話就無法比較取模之前的分數和第一個分數的大小了, 但是我們注意到第一個分數的大小是不會超過1e9的,所以每當第i個小朋友的分數大于1e9的時候就說明答案是最后一個的分數。
代碼:
#include <iostream> #include <algorithm> #include <cstring> #include <stdio.h> using namespace std; const int inf=1e6+7; typedef long long ll; ll arr[inf]; ll special[inf]; ll score[inf];ll max(ll a,ll b) //先嘗試不用取余函數。 {if(a>b)return a;elsereturn b; }int main() {ll n,q;scanf("%lld %lld",&n,&q);for(int i=0;i<n;++i)scanf("%lld",&arr[i]);special[0]=arr[0]; //這里應該是關鍵所在。score[0]=special[0]; //都是從零開始的。ll sum=arr[0];ll themax=arr[0];int lastflag=0;int flag=0;if(arr[0]>=0)flag=1;for(int i=1;i<n;++i){if(sum>0){sum+=arr[i];}else{sum=arr[i];}themax=max(themax,sum);special[i]=themax; //特征值。還不至于爆longlong,if(special[i-1]>=0) //就是這里。重點重點!!!!!!!!!{flag=1;}ll temptemp=score[i-1]+special[i-1];if(flag==0){score[i]=special[0]+score[0];}else{if(temptemp>=score[0])lastflag=1;if(temptemp>1000000000){lastflag=1;temptemp%=q;}score[i]=temptemp;}}if(flag==0||lastflag==0){if(score[0]<0){if(score[0]%q!=0)printf("-");score[0]*=(-1);}printf("%lld\n",score[0]%q);}else{if(score[n-1]<0){if(score[n-1]%q!=0)printf("-");score[n-1]*=-1;}printf("%lld\n",score[n-1]%q);}return 0; }?
總結
以上是生活随笔為你收集整理的2013NOIP普级组-- 小朋友的数字的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 海港
- 下一篇: Traveling on the Axi