UVA 11538(Chess Queen-矩阵对角线长度)

Problem A
Chess Queen
Input:
Standard Input

Output: Standard Output

 

王后互相攻击的前提是在一行,一列,或一对角线。:

 

在 (NxM) 的棋盘上 2 王后互相攻击,求方案数.

 

Input

 

输入数据不超过 5000 行 ,每行为M and N (0< M, N£106) ,数据以0 0结尾.

 

Output

 

每行一个整数表示方案数,保证它在u64范围内.

 

Sample Input                              Output for Sample Input

2 2

100 223

2300 1000

0 0

12

10907100

11514134000                                                                        

 

Problemsetter: Shahriar Manzoor

Special Thanks to: Mohammad Mahmudur Rahman

首先,一个矩形的长宽若为m,n(m>=n)

那么它一个方向的对角线应为1..(n-1)各2条,n有(m-n+1)条

知道这个的化,本题就转化为,在一列一行或一对角线任取2点,有几种取法。

#include<cstdio>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;
#define MAXN (1000000+10)
unsigned long long n,m;
int main()
{
	while (cin>>n>>m&&n&&m)
	{
		if (n>m) swap(n,m);
		cout<<n*m*(n+m-2)+2*n*(n-1)*(3*m-n-1)/3<<endl;
	}
	return 0;
}



CF 287A(IQ Test-枚举3个字符相等的矩阵)

A. IQ Test
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

In the city of Ultima Thule job applicants are often offered an IQ test.

The test is as follows: the person gets a piece of squared paper with a 4 × 4 square painted on it. Some of the square's cells are painted black and others are painted
white. Your task is to repaint at most one cell the other color so that the picture has a 2 × 2 square,
completely consisting of cells of the same color. If the initial picture already has such a square, the person should just say so and the test will be completed.

Your task is to write a program that determines whether it is possible to pass the test. You cannot pass the test if either repainting any cell or no action doesn't result in a 2 × 2 square,
consisting of cells of the same color.

Input

Four lines contain four characters each: the j-th character of the i-th
line equals "." if the cell in the i-th row and the j-th
column of the square is painted white, and "#", if the cell is black.

Output

Print "YES" (without the quotes), if the test can be passed and "NO"
(without the quotes) otherwise.

Sample test(s)
input
####
.#..
####
....
output
YES
input
####
....
####
....
output
NO
Note

In the first test sample it is enough to repaint the first cell in the second row. After such repainting the required 2 × 2 square is on the intersection of the 1-st
and 2-nd row with the 1-st and 2-nd
column.

枚举看是否有一个矩形有3个字符相等
一开始居然把4个判断打错了?《上午也是……

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
using namespace std;
#define MAXLen (4+10)
char a[MAXLen][MAXLen];
bool flag=0;
int main()
{
	for (int i=1;i<=4;i++) scanf("%s",a[i]+1);
	for (int i=1;i<4;i++)
		for (int j=1;j<4;j++)
		{
			if (a[i][j]==a[i][j+1]&&a[i][j]==a[i+1][j]) flag=1;
			if (a[i][j]==a[i][j+1]&&a[i][j]==a[i+1][j+1]) flag=1;
			if (a[i][j]==a[i+1][j]&&a[i][j]==a[i+1][j+1]) flag=1;
			if (a[i+1][j]==a[i][j+1]&&a[i+1][j]==a[i+1][j+1]) flag=1;

		}
	if (flag) printf("YESn");
	else printf("NOn");
	return 0;
}

BZOJ 1084([SCOI2005]最大子矩阵-长矩阵Dp)

1084: [SCOI2005]最大子矩阵

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 586  Solved: 275
[Submit][Status][Discuss]

Description

这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵不能相互重叠。

Input

第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的分值的绝对值不超过32767)。

Output

只有一行为k个子矩阵分值之和最大为多少。

Sample Input

3 2 2

1 -3

2 3

-2 3

Sample Output

9

由于m不超过2
可以暴力Dp
分为m=1和m=2种情况
m=1就不用说了,
F[i][j][k]表示第1行到i第二行到j所能取到的最小值

#include<cstdio>
#include<cstring>
#include<iostream>
#include<functional>
#include<algorithm>
#include<cstdlib>
using namespace std;
#define MAXN (100+10)
#define MAXM (2+1)
#define MAXK (10+1)
int f[MAXN][MAXK],F[MAXN][MAXN][MAXK],n,m,k;
int a[MAXN][MAXN],sum[MAXN][MAXN];
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	sum[0][1]=sum[0][2]=0;
	for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) scanf("%d",&a[i][j]),sum[i][j]=sum[i-1][j]+a[i][j];
	if (m==1)
	{
		memset(f,0,sizeof(f));
		for (int i=1;i<=n;i++)
		{
			f[i][0]=0;
			for (int l=1;l<=k;l++)
			{
				f[i][l]=f[i-1][l];
				for (int j=0;j<i;j++)
				{
					f[i][l]=max(f[i][l],f[j][l-1]+sum[i][1]-sum[j][1]);
				}
			}
		}
		cout<<f[n][k]<<endl;
	}
	else
	{
		memset(F,0,sizeof(F));
		for (int i=1;i<=n;i++)
		{
			for (int j=1;j<=n;j++)
			{
				F[i][j][0]=0;
				for (int l=1;l<=k;l++)
				{
					F[i][j][l]=max(F[i-1][j][l],F[i][j-1][l]);
					for (int i2=0;i2<i;i2++) F[i][j][l]=max(F[i][j][l],F[i2][j][l-1]+sum[i][1]-sum[i2][1]);
					for (int j2=0;j2<j;j2++) F[i][j][l]=max(F[i][j][l],F[i][j2][l-1]+sum[j][2]-sum[j2][2]);
					if (i==j)
						for (int j2=0;j2<i;j2++)
						{
							F[i][i][l]=max(F[i][i][l],F[j2][j2][l-1]+sum[i][1]-sum[j2][1]+sum[j][2]-sum[j2][2]);
						}
				}
			}
		}

		cout<<F[n][n][k]<<endl;

	}


	return 0;
}

POJ 3070(Fibonacci-矩阵幂)

Language:
Fibonacci
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 6733   Accepted: 4765

Description

 Fibonacci integer sequence指 F0 = 0, F1 = 1, and Fn = Fn − 1 + Fn − 2 for n ≥ 2. eg:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …

Fibonacci 的矩阵乘法求法如下

.

Given an integer n, 求 Fn mod 10000.

Input

多组数据,每行一个 n (where 0 ≤ n ≤ 1,000,000,000). 数据以 −1 结尾.

Output

对每组数据打印一行 Fn mod 10000).

Sample Input

0
9
999999999
1000000000
-1

Sample Output

0
34
626
6875

Hint

As a reminder, matrix multiplication is associative, and the product of two 2 × 2 matrices is given by

.

Also, note that raising any 2 × 2 matrix to the 0th power gives the identity matrix:

.

Source

正宗矩阵幂练手题

做了这题就差不多理解矩阵乘法了。

补充:递归一般能用矩阵乘法,如f[i]=g(f[i-1],f[i-2])...

    但是规划不行,如f[i]=max(....)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<functional>
using namespace std;
#define MAXN (1000000000)
#define F (10000)
struct M
{
	int a[3][3];
	M(int i){a[1][1]=a[1][2]=a[2][1]=1;a[2][2]=0;	}
	M(){memset(a,0,sizeof(a));	}
	friend M operator*(M a,M b)
	{
		M c;
		for (int i=1;i<=2;i++)
			for (int j=1;j<=2;j++)
				for (int k=1;k<=2;k++)
				{
					c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%F;
				}
		return c;
	}
	friend M pow(M a,int b)
	{
		if (b==1)
		{
			M c(1);
			return c;
		}
		else
		{
			M c=pow(a,b/2);
			c=c*c;
			if (b%2) return c*a;
			return c;
		}
	}
};
int n;
int main()
{
	while (cin>>n&&n!=-1)
	{
		if (n==0) printf("0n");
		else
		{
			M a=pow(M(1),n);
			printf("%dn",a.a[1][2]);
		}
	}
}

CF 253D(矩阵-4角相等且矩阵权值有上限的矩阵数)

D. 4a矩阵
time limit per test

2 seconds

memory limit per test

256 megabytes

input

input.txt

output

output.txt

有一个 n × m 的矩阵, 行 1 到 n,
列1 to 
m.

4a矩阵定义:

  • 矩阵内最多有 k 个 "a" ;
  • 4个角相等,长宽大于1.

请在给定矩阵中数出有几个子矩阵是4a矩阵.

Input

第一行3个整数n, m, k (2 ≤ n, m ≤ 400; 0 ≤ k ≤ n·m).

接下来为矩阵.

Output

一个整数,表示4a矩阵数.

Sample test(s)
input
3 4 4
aabb
baab
baab
output
2
input
4 5 1
ababa
ccaca
ccacb
cbabc
output
1
Note

第一个样例的解 (2, 2) (3, 3),

(2, 1) 
(3, 4).

这题是状态压缩问题。

用s[i][j]=∑a[1][j]+a[2][j]+..+a[i][j]

那么我们只需要枚举3个量

行的上下,还有列的

显然r列的关系可以由r-1的关系推出。



#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<cstdlib>
using namespace std;
#define MAXN (400+10)
#define MAXM (400+10)
int n,m,k;
char a[MAXN][MAXM];
int s[MAXN][MAXM];  //表示s[i][j]=a[1][j]+a[2][j]+..a[i][j]
int c[1<<8];
int main()
{
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);


	memset(s,0,sizeof(s));
	scanf("%d%d%dn",&n,&m,&k);
	for (int i=1;i<=n;i++)
	{
		gets(a[i]+1);
		for (int j=1;j<=m;j++)
		{
			s[i][j]=s[i-1][j]+(a[i][j]=='a');
		}
	}
	long long ans=0;
	/*
	for (int i=1;i<=n;i++)
	{
		for (int j=1;j<=m;j++)
			cout<<s[i][j]<<' ';
		cout<<endl;
	}
	*/
	;
	for (int i=1;i<n;i++)
	{
		for (int j=i+1;j<=n;j++)
		{
			int l=1,tot=0;
			memset(c,0,sizeof(c));
			for (int r=1;r<=m;r++)
			{
				tot+=s[j][r]-s[i-1][r];
				while (tot>k)
				{
					tot-=s[j][l]-s[i-1][l];
					c[a[i][l]]-=(a[i][l]==a[j][l]);
					l++;
				}
				if (l<r&&a[i][r]==a[j][r]) ans+=c[a[i][r]];
				if (a[i][r]==a[j][r]) c[a[i][r]]++;
			}
		}
	}
	cout<<ans<<endl;
	return 0;
}