J - The Lesson of Physical Culture
Time Limit:1500MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u
Description
In one of the schools in Berland, the teacher of physical culture got cold during the morning excercises. After some discussion the pedagogical assembly has made a decision that the next lesson of physical culture will be driven by the teacher of mathematics Gleb Antonovich, who does not care whom, where and when he should talk about mathematics.
After coming to the gym, Gleb Antonovich noticed that the floor is the N x M grid of unit squares. The first exercise of the lesson was to stand in some cells in such a way that any student is in the center of some cell, there is no more than one student in any cell, and there are no more than two students in any 2x 2 square to prevent discomfort. But because of the limited space, it was required that each square 2x 2 must contain two students.
Gleb Antonovich is now interested, how many different ways of such standing exist if all students are equivalent. Your task is to find the number.
Input
The first line contains two integers
N
and
M
(2 ≤
N,
M≤ 1000).
Output
Output the number of ways without any leading zeros or spaces. Note that the number of students standing on the floor is not fixed.
Sample Input
sample input | sample output |
2 2 | 6 |
题意:求解一个N*M的矩形方格每一个小方格中最多有一个人,每个2*2的方格中必须有两个人的方法数。
方格有人时,值为1否则为0;
则第一行的除了0101010和101010这两种站法外,还有2的m次幂减2种方法,接下来的n-1行就已经确定了。
如果第一行为101010或0101010的话,那么接下来的n-1行,每行都有2种选法。则有2的n次幂;
即总的为2^n+2^m-2种方法。
代码如下:
#include<stdio.h>
#include<string.h>
#include<algorithm>
char a[1010];
char b[1010];
char c[1010];
void deal(char *a,char *b){
int lena=strlen(a);
int lenb=strlen(b);
int len;
memset(c,'0',sizeof(c));
int i,j,t;
for(i=0;i<lena;i++){
int arr=0;
for(j=0;j<lenb;j++){
t=(c[i+j]-'0')+(a[i]-'0')*(b[j]-'0')+arr;
c[i+j]=t%10+'0';
arr=t/10;
}
if(arr!=0){
c[i+j]=arr+'0';
}
}
for(i=1009;i>=0;i--){
if(c[i]!='0') break;
}
memset(b,0,sizeof(b));
len=i+1;
for(i=0;i<len;i++){
b[i]=c[i];
}
b[len]=0;
memset(c,0,sizeof(c));
}
void make(char b1[],char b2[]){
int i,len1,len2,j;
len1=strlen(b1);
len2=strlen(b2);
if(len1<len2){
int tp=len2;
char cc[1010];
strcpy(cc,b2);
memset(b2,0,sizeof(b2));
len2=len1;
strcpy(b2,b1);
memset(b1,0,sizeof(b1));
len1=tp;
strcpy(b1,cc);
}
for(i=len2;i<len1;i++){
b2[i]='0';
}
int arr=0;
for(i=0;i<len1;i++){
int t=(b1[i]-'0')+(b2[i]-'0')+arr;
b1[i]=t%10+'0';
arr=t/10;
}
if(arr!=0){
b1[len1]=arr+'0';
b1[len1+1]=0;
}else{
b1[len1]=0;
}
}
int main(){
int n,m,i;
while(~scanf("%d %d",&n,&m)){
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
a[0]='2';
b[0]='2';
for(i=1;i<m;i++){
deal(a,b);
}
char b1[1010];
memset(b1,0,sizeof(b1));
strcpy(b1,b);
b1[0]=b1[0]-2;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
a[0]='2';
b[0]='2';
for(i=1;i<n;i++){
deal(a,b);
}
char b2[1010];
memset(b2,0,sizeof(b2));
strcpy(b2,b);
make(b1,b2);
int len=strlen(b1);
for(i=len-1;i>=0;i--){
printf("%c",b1[i]);
}
puts("");
}
return 0;
}