【数学】礼物(jzoj 2129)
生活随笔
收集整理的這篇文章主要介紹了
【数学】礼物(jzoj 2129)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
禮物
jzoj 2129
題目大意
有1……n,n個禮物盒,第i個禮物盒有i個禮物,現在讓你選2個禮物盒,使他是k的倍數
輸入樣例
1 1 3 2 5 2 50 50 0 0輸出樣例
0 1 4 24數據范圍
20%的數據N<=100;
80%的數據K<=1000;
每個輸入文件最多有200行輸入數據。
解題思路:
對于20%的數據,我們可以直接暴力
對于80%的數據,我們可以按%k得到的值來分類,如果兩個數%剩的值加在一起等于k那說明這兩個數是合法的一對
正解:
首先我們圖文結合(如下圖)
首先我們把nnn按kkk來分(第2步)
然后我們把n/kn/kn/k定為xxx
每一個k中都有一個被整除的(第3步右側),那x個被整除的,可以組成(x?1)?x2\frac{(x-1)*x}{2}2(x?1)?x?對
然后剩下的k?1k-1k?1我們分為奇偶數(第4步)
奇數:把中間除外的互相相乘,得到h?x?xh*x*xh?x?x對(h為一半,每個余數都有x個數,兩個就有x?xx*xx?x對),然后剩下的一個(第5步)和其他k中的中間相乘,得到(x?1)?x2\frac{(x-1)*x}{2}2(x?1)?x?對
偶數:直接相乘
然后處理余數:
不到一半或在一般前面的部分就直接和另一側的x個數相配(第6步)
如果有中間1塊就和前面xxx個中間1塊相配(第8步)
大于一半的就和一半前的x+1x+1x+1相配(+1是因為第6步使一半前的加上了1)
注:解題思路寫地不好請見諒
代碼:
#include<cstdio> #define min(a,b) (a)<(b)?(a):(b) using namespace std; long long n,k,x,ys,h,ans; int main() {scanf("%lld %lld",&n,&k);while (n&&k){x=n/k;//如解題思路ys=n%k;//余數h=(k-1)/2;//減去整除部分后的一半ans=x*(x-1)/2+x*x*h;//整除部分和普通部分if ((k-1)%2) ans+=x*(x-1)/2;//奇數的中間部分if (ys>0) ans+=(min(ys,h))*x,ys-=h;//余數的左邊部分if (ys>0&&(k-1)%2) ans+=x,ys--;//奇余數的中間部分if (ys>0) ans+=ys*(x+1);//余數的右邊部分printf("%lld\n",ans);scanf("%lld %lld",&n,&k);}return 0; } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的【数学】礼物(jzoj 2129)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 索尼高管:PS5 游戏主机已不再供不应求
- 下一篇: 纪中C组模拟赛总结(2019.7.12)