題解 CF1034B Little C Loves 3 II
題意
給定一個 \(n\times m\) 的棋盤,每次可以在上面放一對棋子 \((x,y)\),\((x',y')\),要求 \(|x-x'|+|y-y'|=3\),問最多可以放多少個棋子。
題解
本題中的「一對棋子」本質上只有如下兩種擺放方式。
- \(||x-x'|-|y-y'||=3\)。
- \(||x-x'|-|y-y'||=1\)。
我們用這兩種擺放方式可以湊出如下四種完整的棋盤。
- \(1\times6\)
- \(2\times4\)
- \(2\times5\)
- \(3\times4\)
當 \(n\),\(m\) 足夠小時,情況可能會有些特殊,我們先單獨考慮這些情況。
情況 1 : \(n=1\) 或 \(m=1\)
不難發現只能使用第 \(1\) 種擺法。
每 \(6\) 個為一迴圈節,剩下 \(x\) 個格若多於 \(3\) 個又可以放 \(x-3\) 對。
所以答案為 \(\lfloor\dfrac{\max(n,m)}{6}\rfloor\times6+\max(0,\max(n,m)\mod6-3)\times2\)。
情況 2 : \(n=2\) 或 \(m=2\)
不妨設 \(n=2\)。
此時,若 \(m=4a+5b+6c\) 有自然數解,則 \(2\times m\) 的棋盤可以用 \(a\) 個 \(2\times4\) 的棋盤,\(b\)
不難得出只有 \(m=2,3,7\) 時無解。
所以 \(n=m=2\) 時,答案為 \(0\);\(n=2,m=3\) 或 \(m=2,n=3\) 時,答案為 \(4\);\(n=2,m=7\) 或 \(m=2,n=7\) 時,答案為 \(12\);否則答案為 \(n\times m\)。
情況 3 : \(2|n,n\ge4,m\ge3\) 或 \(2|m,m\ge4,n\ge3\)
不妨 \(2|n\),\(n=2k\)。
若 \(m\ne3,7\),則可以由 \(k\)
若 \(m=7\),則可以用 \(k\) 個 \(2\times5\) 的棋盤和 \(1\) 個 \(2\times2k\) 的棋盤拼成,答案為 \(n\times m\)。
若 \(m=3,2|k\),設 \(k=2t\),則 \(n=4t\),可以用 \(t\) 個 \(3\times4\) 的棋盤拼成,答案為 \(n\times m\)。
若 \(m=3,2\nmid k\),設 \(k=2t+1\),則 \(n=4t+2\ge6\),可以用 \((t-1)\) 個 \(3\times4\) 的棋盤和 \(3\) 個 \(1\times6\) 的棋盤拼成,答案為 \(n\times m\)。
所以這類情況答案均為 \(n\times m\)。
情況 4 : \(2\nmid n,2\nmid m,n\ge3,m\ge3\)
不難發現答案一定不超過 \(n\times m-1\),且藉助 \(1\times6\) 的棋盤可知一定情況下,\(n\times m\) 的棋盤與 \((n\mod6)\times(m\mod6)\) 的棋盤等價。
情況 4.1 : \(n\mod6=3\) 或 \(m\mod6=3\)
不妨設 \(n\mod6=3\),則這等價於 \(n=3,m\ge3\)。
對於任意大等於 \(3\) 的奇數 \(m\),我們總可以按如下方法遞迴地構造出如下圖形。
\(m=3\):
\(m=5\):
\(m=7\):
\(m=9\):
對於最後一個圖形我們可以這樣擺放棋子:
此時總共放了 \(n\times m-1\) 個棋子,達到最優狀態,故答案為 \(n\times m-1\)。
情況 4.2 : \(n\mod6=5\) 或 \(m\mod6=5\)
不妨設 \(n\mod6=5\),則這等價於 \(n=5,m\ge3\)。
藉助 \(2\times5\) 的棋盤可知,這等價於 \(1\times5\) 的棋盤。
而 \(1\times5\) 的棋盤上最多可擺放 \(4\) 個棋子,此時總共放了 \(n\times m-1\) 個棋子,達到最優狀態,故答案為 \(n\times m-1\)。
情況 4.3 : \(n\mod6=1\) 且 \(m\mod6=1\)
這等價於 \(n=m=1\),此時總共放了 \(n\times m-1\) 個棋子,達到最優狀態,故答案為 \(n\times m-1\)。
Code
#include<bits/stdc++.h>
#define LL long long
using namespace std;
LL n,m,ans;
template<class T>void read(T &x)
{
x=0;int f=0;char ch=getchar();
while(ch<'0' || ch>'9')f|=(ch=='-'),ch=getchar();
while(ch>='0' && ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
x=f? -x:x;return ;
}
inline LL max(LL a,LL b)
{
return a>b? a:b;
}
int main()
{
read(n),read(m);
if(n==1 || m==1)return 0&printf("%lld",(max(n,m)/6)*6+max(0,(max(n,m)%6)-3)*2);
if(n==2 && m==2)return 0&printf("0");
if((!(n&1) && m>=3) || (!(m&1) && n>=3))return 0&printf("%lld",((n*m)/2-((n==2 && m==3) || (m==2 && n==3) || (n==2 && m==7) || (m==2 && n==7)))*2);
if((n%6)==3 || (m%6)==3)return 0&printf("%lld",((n*m)/2)*2);
if((n%6)==5 || (m%6)==5)return 0&printf("%lld",((n*m)/2)*2);
return 0&printf("%lld",((n*m)/2)*2);
}