题目链接:点击打开链接
题意:一个n*M的棋盘上让你放马,马和马之间不能攻击。问能放多少匹马。
题解:最开始是以为是一道搜索题。然后一看数据范围。瞬间懵逼。发现这道题,是个规律题。而且规律错综复杂。死活没有思路。然后我们队里的dalao告诉我。你看一眼国际象棋的棋盘你就能明白这道题了。然后我就看了一下棋盘,发现如下规律
当 n == 1 || m == 1 时
结果为 n和m的最大值。
当 m == 2 时 n为偶数时
结果同上
当 m == 2 时 n为奇数时
结果为 上面的结果+1 (样例为 2 5 结果为 6,这一组卡了我10年)
n==2的情况和上面m==2的情况相同
其余情况 为 黑色格子 和白色格子多的。为结果。
放一份能AC这道题 ,但是不对的代码。(别问我为什么能AC这道题,因为我对拍出来的)
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1050;
int mp[maxn][maxn];
int main(){
memset(mp,0,sizeof(mp));
for(int i = 1 ; i < 1050 ;i ++){
for(int j = 1 ; j < 1050 ;j ++){
if(i%2){
if(j%2){
mp[i][j] = 1;
}
}
else {
if(j%2 == 0){
mp[i][j] = 1;
}
}
}
}
// freopen("e:\\duipai\\data.txt","r",stdin);
// freopen("e:\\duipai\\out2.txt","w",stdout);
int z = 1000000;
// while(z--){
int n,m;
cin >> n >> m;
if(n == 1 || m == 1){
cout << max(m,n)<<endl;
return 0;
}
if(n == 2 || m == 2){
if(n == 2){
if(m % 2){
cout << max(n,m)+1 <<endl;
}
else cout << max(m,n) << endl;
}
if(m == 2){
if(n % 2){
cout << max(n,m)+1 <<endl;
}
else cout << max(m,n) << endl;
}
return 0;
}
int ans1 = 0 ;
for(int i = 1 ; i <= n ; i ++){
for(int j = 1; j <= m ;j ++){
ans1 += mp[i][j] ;
}
}
int ans2 = 0;
for(int i = 1 ; i <= n ; i ++){
for(int j = 1; j <= m ;j ++){
if(!mp[i][j])
ans2 ++;
}
}
cout << max(ans1,ans2) << endl;
// }
}
再放一份正确无误的代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
//freopen("e:\\duipai\\data.txt","r",stdin);
// freopen("e:\\duipai\\out1.txt","w",stdout);
int n,m;
int z = 1000000;
while(z--)
{
cin>>n>>m;
if(n == 1 || m == 1)
{
printf("%d\n",m == 1 ? n : m);
}
else if(n == 2 || m == 2)
{
if(m == 2) swap(n,m);
int ans = m/4*4;
if(m%4 == 1)
{
ans+=2;
}
else if(m%4!=0)
{
ans+= 4;
}
printf("%d\n",ans);
}
else
{
if(n*m%2 == 0)
{
printf("%d\n",n*m/2);
}
else printf("%d\n",n*m/2+1);
}
}
}