CodeForces - 1036B Diagonal Walking v.2(思维)
題目鏈接:點擊查看
題目大意:給出m個詢問,每個詢問給出x y k,每次可以向當前點周圍的八個方向移動,每個點可以經過任意次數,問從(0,0)點走到(x,y)點,使用的步數恰好為k時,走過的斜邊的最大數目
題目分析:找規律的題,首先選出m和n中較大的那條邊(這里我們假設m>=n),我們完全可以每次都斜著走,走m次后,一定能到(m,m)點,由于從(0,0)的距離到(m,m)的距離肯定大于等于到(n,m)的距離,所以我們可以反過來想,如果k小于m的話,那么最遠也只能到達(k,k)點,所以無法達到(n,m)點,這個是一種判斷,另一種是,如果m和n做差,結果是偶數的話,一定可以全部通過走斜邊的方式經過(n,m)點,注意這里是經過而不是到達,具體的下面再說。我們接著分析,那如果是奇數的話,肯定需要用一次步數來橫著走一次或豎著走一次才行,所以如果m和n做差的結果是奇數的話,我們令k-1。如果是偶數的話,我們還需要討論k和m的關系,如果k和m的差值是偶數的話,那每當走到(n,m)點后,可以找一個鄰近的斜邊進行反復的來回走動,因為是偶數,所以最后走完k次后肯定會回到(n,m)點,所以答案就是k,但如果k和m的差值是奇數,那就說明先走到(n,m)點后來回反復走動,走完k次后,會回不到(n,m)點,那么我們就需要橫著或豎著多走兩次才行,這樣就可以和最后的那一次斜著走抵消了,如果滿足這個條件令k-2即可,分類討論一下每種情況,最后輸出k即可
上代碼:
#include<iostream> #include<string> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<cstdio> using namespace std; typedef long long LL;const int N=25;int main() {int w;cin>>w;while(w--){LL n,m,k;scanf("%lld%lld%lld",&n,&m,&k);if(m<n)swap(n,m);if(m>k){printf("-1\n");continue;}if((m-n)&1)//兩邊相差為奇數時,需要多走一個橫著或豎著 k--;else if((k-m)&1)//兩邊相差為偶數時,如果剩余步數為奇數,需要多走兩個橫著或豎著k-=2;printf("%lld\n",k);//兩邊相差為偶數,且剩余步數為偶數時,k次全部用來斜著走即可}return 0; }?
總結
以上是生活随笔為你收集整理的CodeForces - 1036B Diagonal Walking v.2(思维)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中石油训练赛 - The King’s
- 下一篇: HDU - 5875 Function(