题目描述:
用一种L形骨牌(长3宽2)覆盖一个M×N的矩形地板,问能否完全覆盖。若不能,输出最少不能覆盖的方块数。
分析:
先解释一下题目 ,骨牌样子如下图。题目中没有说明M,N的范围。实际数据中可能长达100位……
推规律推了半天,只找到一些皮毛规律。
最初的想法是,2个L骨牌拼成一个2×4的矩形,从大尺度来看,就像一个1×2的多米诺骨牌~ 如果MN都是偶数的话,将MN除2,就变成了多米诺骨牌覆盖问题。
但这只是其中一种情况,后来发现3×8的矩形也能用L骨牌覆盖……后来就想不下去了……※×¥◎~
最终在衡阳八中论坛上找到一个Pascal代码,将其翻译成C就AC了>_<||(不要BS我)
决不白Copy人家代码,还是解释一下最后的结论吧:
1,若M或N等于1,那么所有的方块都不能覆盖。
2,若M×N是8的倍数,那么可以完全覆盖。
3,若M×N是4的倍数,则剩余4;否则,剩余( M×N )%4。
自己理解吧,说一下关于MN很大的问题。
我看到的程序中,处理MN的时候,只用了MN的最后3位数代替了MN。后来一想也能明白,因为我们只关心MN是否是8的倍数,只与最后3位有关。嘿嘿~
在百度搜“ZJU2028”的时候发现有且仅有衡阳八中一个结果……
这篇文章写完后应该是第二个参考资料吧~呵呵:)
#include <stdio.h>
#include <string.h>
#define N 102
int atoi(char *s){
int i=0,m=strlen(s);
s+=m>3?m-3:0;
while(*s){
i=i*10+*(s++)-'0';
}
return i;
}
int main()
{
char x[N],y[N],cx,cy;
int p,q,ans;
while(scanf("%s%s",x,y)!=EOF){
p=atoi(x);
q=atoi(y);
ans=(p*q)%8;
if(ans>4) ans-=4;
if(!strcmp(x,"1") || !strcmp(y,"1")) printf("%s/n",!strcmp(x,"1")?y:x);
else if(ans) printf("%d/n",ans);
else printf("Yes/n");
}
}