T1
P1123 取数游戏
题目描述
一个N \times MN×M的由非负整数构成的数字矩阵,你需要在其中取出若干个数字,使得取出的任意两个数字不相邻(若一个数字在另外一个数字相邻88个格子中的一个即认为这两个数字相邻),求取出数字和最大是多少。
输入输出格式
输入格式:
第1行有一个正整数TT,表示了有TT组数据。
对于每一组数据,第一行有两个正整数NN和MM,表示了数字矩阵为NN行MM列。
接下来NN行,每行MM个非负整数,描述了这个数字矩阵。
输出格式:
TT行,每行一个非负整数,输出所求得的答案。
输入输出样例
输入样例#1: 复制
3
4 4
67 75 63 10
29 29 92 14
21 68 71 56
8 67 91 25
2 3
87 70 85
10 3 17
3 3
1 1 1
1 99 1
1 1 1
输出样例#1: 复制
271
172
99
说明
对于第1组数据,取数方式如下:
[67] 75 63 10
29 29 [92] 14
[21] 68 71 56
8 67 [91] 25
对于20\%20%的数据,N, M≤3N,M≤3;
对于40\%40%的数据,N,M≤4N,M≤4;
对于60\%60%的数据,N, M≤5N,M≤5;
对于100\%100%的数据,N, M≤6,T≤20N,M≤6,T≤20。
每次先检查前四个点
#include <iostream>
#include<string.h>
#include<cmath>
using namespace std;
int a[10][10];
bool b[10][10];
int sum;
int m,n;
void dfs(int x, int y,int ans)
{
if(y>=n+1)
y=1,x++;
if(x>=m+1)
{
sum=max(sum,ans);
return ;
}
if(!b[x-1][y+1]&&!b[x-1][y]&&!b[x-1][y-1]&&!b[x][y-1])//选择这个点
{
b[x][y]=true;
dfs(x,y+1,ans+a[x][y]);
b[x][y]=false;
}
dfs(x,y+1,ans);//不选择这个点
}
int main()
{
int t;
cin >>t;
while(t--)
{
memset(b,0,sizeof(b));
cin >> m >> n;
for(int i=1; i<=m; i++)
{
for(int j=1; j<=n; j++)
{
cin >> a[i][j];
}
}
dfs(1,1,0);
cout<<sum<<endl;
sum=0;
}
return 0;
}
T2
题目描述
某人写了n封信和n个信封,如果所有的信都装错了信封。求所有信都装错信封共有多少种不同情况。
输入输出格式
输入格式:
一个信封数n(n<=20)
输出格式:
一个整数,代表有多少种情况。
输入输出样例
输入样例#1: 复制
2
输出样例#1: 复制
1
输入样例#2: 复制
3
输出样例#2: 复制
2
暴搜只能过一半,TLE
正解是错排
TLE的代码
#include <iostream>
using namespace std;
int a[25];
int b[25];
bool v[25];
int n;
int num;
void dfs(int x)
{
if(x==n+1)
{
num++;
return ;
}
for(int i=1;i<=n;i++)
{
if(a[x]!=b[i]&&!v[i])
{
v[i]=true;
dfs(x+1);
v[i]=false;
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
a[i]=i;
b[i]=i;
}
dfs(1);
cout<<num<<endl;
return 0;
}
正解
#include<iostream>
using namespace std;
long long f[30];
int main()
{
int n;
cin >> n;
f[1]=0;
f[2]=1;
for(int i=3;i<=n;i++)
{
f[i]=(i-1)*(f[i-1]+f[i-2]);
}
cout<<f[n]<<endl;
return 0;
}
T3
P1387 最大正方形
题目描述
在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长。
输入输出格式
输入格式:
输入文件第一行为两个整数n,m(1<=n,m<=100),接下来n行,每行m个数字,用空格隔开,0或1.
输出格式:
一个整数,最大正方形的边长
输入输出样例
输入样例#1: 复制
4 4
0 1 1 1
1 1 1 0
0 1 1 0
1 1 0 1
输出样例#1: 复制
2
枚举每个点,作为正方形的左上角顶点
#include <iostream>
#include<cmath>
using namespace std;
int a[105][105];
int main()
{
int n,m;
cin >> n >>