一、感想
夜のほとんどは、ちょっとああ、説明を書くために!その無感情的な興奮として無敵右!あなたのためにあなたのためのよう!あなたがアイデアを読み、問題の午後溶液に再びそれを確認する前に、結果は夜の十時には、ちょっとああ停止されていない停止するために少しの変化をノックされます!
完成した少なくとも一つの30。私がクラブにいました。午前中に半年以上のアルゴリズムの実験的クラスにまで取得します。よく栽培寝ていません。
ねえ、スキルを向上させる必要性を認識しています。
二、题意
最大の製品検索「クロスを。」図クロス被写体に示すような形状。各生成物中の×印の数で乗算されます。もちろん暴力的ではない、のn * n個の*のm * mのないジョーク。しかし、達成し、各方向の接頭辞で前処理してもよいし、各点O(1)(1)各ポイントの最大値を読み出しOにわたる最大クロス最後のスイープを見つけます。
プレフィックス処理8つの方向と各方向に「終わり」からプロセスを開始することで、エンドは法律を見つけるために、独自の数式を記述する必要があり、すべてのポイントを再度実行し、その後、先見この電流の向きをバックに従っていませんないライン上の範囲外。
生成物は、それが有用であり、合計対数ように変換されます。
コードをバックノック、およびのみ再度、前処理された掃引テーブルが存在するから読み出さの総数にわたる各最初の掃引の位置は、この操作は非常に容易になります。
基本的な使用のconst int型_n = 7が、今日は、一番上の書き込みのconstドラッグをノックノック気にしないでください、だけでなく、考え方は私が直接のconst書き込む場所がわからない、手のけいれんが十億九を打つ+ 1E9は、良い、以下をプレイした結果0。愚か後に再びそれを行います。
その後、自動的にグローバルな初期値で定義された変数を定義し、私はほとんどの時間が0であると感じ?あなたはそれで初期値の独自の定義を記述する必要があります。10のうち、入力されたREサイクルで何を行っていないし、何の変数の初期値は、出力が答え、REを持っていたために割り当てられていないされていません。イェジンハオ、クロスボーダーのアレイと、この空想REの方法に加えてREへの洞察。
#include<bits/stdc++.h>
using namespace std;
int dir[8][2] = {-1, -1, -1, 1, 1, -1, 1, 1,
0, 1, 0, -1, 1, 0, -1, 0};
const int mx = 1e3 + 5;
char a[mx][mx];
double logs[mx][mx];
int pre[8][mx][mx];
double sum[8][mx][mx];
int n;
bool in(int x){
return x >= 0 && x < n;
}
void pre_work(){
double lg2 = log(2), lg3 = log(3);
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++){
if(a[i][j] == '2') logs[i][j] = lg2;
if(a[i][j] == '3') logs[i][j] = lg3;
}
int k;//用来计数 看最多有几个可以伸展
for(int di = 0; di < 8; di++){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
int d1 = dir[di][0], d2 = dir[di][1];
if(!in(i - d1) || !in(j - d2)){//预处理这个方向每个点非零数个数
//并预处理前缀和
k = 0;
int x = i, y = j;
while(in(x) && in(y)){
if(a[x][y] != '0'){
k++;
if(x == i && y == j) sum[di][x][y] = logs[i][j];
else sum[di][x][y] = sum[di][x-d1][y-d2] + logs[x][y];
}
else {
sum[di][x][y] = 0;
k = 0;
}
pre[di][x][y] = k;//这个k是包括自己在内的长度
x += d1, y += d2;
}
}
}
}
}
}
int main(){
cin >> n;
for(int i = 0; i < n; i++){
scanf("%s", a[i]);
}
pre_work();
// for(int i = 0; i < n; i++){
// for(int j = 0; j < n; j++){
// cout << pre[2][i][j] << " ";
// }
// cout << '\n';
// }
int ansdir = 0;
double val = 0;
int fx = 0, fy = 0;
int f_len = 0;
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++){//找到最大的十字架
if(a[i][j] == '0') continue;
int len = n + 1;
for(int di = 0; di < 4; di++){
len = min(len, pre[di][i][j]);
}
// cout << i << ' ' << j << ":" << len << endl;
double s = logs[i][j];
for(int k = 0; k < 4; k++){
s += (sum[k][i + (len-1)*dir[k][0]][j + (len-1)*dir[k][1]] - sum[k][i][j]);//不用把自己加上
}
// cout << i << ' ' << j << ":" <<len <<' '<< s << endl;
if(s > val){
f_len = len;
val = s;
fx = i, fy = j;
ansdir = 0;
}
len = n + 1;
for(int di = 4; di < 8; di++){
len = min(len, pre[di][i][j]);
}
// cout << i << ' ' << j << ":" << len << endl;
s = logs[i][j];
//s是以s为十字架中心能到的最大lg(乘积)
for(int k = 4; k < 8; k++){
s += (sum[k][i + (len-1)*dir[k][0]][j + (len - 1)*dir[k][1]] - sum[k][i][j]);//不用把自己加上
}
// cout << i << ' ' << j << ":" <<len <<' '<< s << endl;
if(s > val){
f_len = len;
val = s;
fx = i, fy = j;
ansdir = 4;
}
}
//val是前面的 val1是后面的
int k = ansdir;
long long ans = a[fx][fy] - '0';
for(int di = k; di < 4 + k; di++){
for(int i = 1; i < f_len; i++){
ans *= a[fx + i * dir[di][0]][fy + i * dir[di][1]] - '0' ;
ans %= 1000000007;
}
}
cout << ans << endl;
return 0;
}