连续四场比赛都是后几个小时眼睁睁的看着排名往下掉,却无能为力。。。。心脏实在是受不了。。。。
好久没写题解了。。。。来贴一下代码。。。。
1002 貌似是原题。。。
然后我WA五发。。。。
只因初始化是2。。。。。。2333333333333333333
AC代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
int col[8400000];
int N, M;
int lc( int root ){
return 2 * root;
}
int rc( int root ){
return 2 * root + 1;
}
void PushDown( int root ){
if( col[root] != -1 ){
col[lc(root)] = col[rc(root)] = col[root];
col[root] = -1;
}
}
void PushUp( int root ){
if( col[lc(root)] == col[rc(root)] && col[lc(root)] != -1 ){
col[root] = col[lc(root)];
}
}
void Updata( int color, int l, int r, int L, int R, int root ){
if( l <= L && r >= R ){
col[root] = color;
return;
}
PushDown( root );
int mid = ( L + R ) / 2;
if( l <= mid ) Updata( color, l, r, L, mid, lc( root ) );
if( r > mid ) Updata( color, l, r, mid + 1, R, rc( root ) );
PushUp( root );
}
int query( int l, int r, int L, int R, int root, __int64 st ){
if( l <= L && r >= R && col[root] != -1 ){
if( col[root] != -1 ){
st |= 1 << ( col[root] );
}
return st;
}
if( L == R ){
if( col[root] != -1 ){
st |= 1 << ( col[root] );
}
return st;
}
int mid = ( L + R ) / 2;
int ans = st;
PushDown( root );
if( l <= mid ) ans = query( l, r, L, mid, lc( root ), ans );
if( r > mid ) ans = query( l, r, mid + 1, R, rc( root ), ans );
PushUp( root );
return ans;
}
int main(){
char s[10];
while( scanf( "%d%d", &N, &M ) && !( N == 0 && M == 0 ) ){
for( int i = 1; i <= 8 * N; i++ ){
col[i] = 2;
}
for( int i = 1; i <= M; i++ ){
scanf( "%s", s );
if( s[0] == 'P' ){
int temp1, temp2, temp3;
scanf( "%d%d%d", &temp1, &temp2, &temp3 );
Updata( temp3, temp1, temp2, 1, N, 1 );
}else{
int temp1, temp2;
scanf( "%d%d", &temp1, &temp2 );
__int64 ans = query( temp1, temp2, 1, N, 1, 0 );
int i;
bool flag = false;
for( i = 1; i <= 30; i++ ){
if( ans & ( 1LL << i ) ){
printf( "%d", i );
i++;
flag = true;
break;
}
}
for( ; i <= 30; i++ ){
if( ans & ( 1LL << i ) ){
printf( " %d", i );
}
}
if( flag ) printf( "\n" );
}
}
}
return 0;
}
/*
5 100
P 5 5 30
Q 5 5
*/
1003. 爆搜也行 我用dp过的。。。枚举拐弯的点。。。
dp快点0ms。。。。
然后先dp处理下每个方向上的最长延伸。。。。
AC代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
char s[110][110];
int dp[10][110][110];
int N;
int main(){
while( scanf( "%d", &N ) && N ){
for( int i = 1; i <= N; i++ ){
scanf( "%s", &s[i][1] );
}
memset( dp, 0, sizeof( dp ) );
for( int i = 1; i <= N; i++ ){
for( int j = 1; j <= N; j++ ){
if( s[i][j] == '.' ){
dp[1][i][j] += 1 + dp[1][i-1][j-1];
dp[2][i][j] += 1 + dp[2][i-1][j];
dp[4][i][j] += 1 + dp[4][i][j-1];
}
}
}
for( int i = 1; i <= N; i++ ){
for( int j = N; j >= 1; j-- ){
if( s[i][j] == '.' ){
dp[3][i][j] += 1 + dp[3][i-1][j+1];
dp[5][i][j] += 1 + dp[5][i][j+1];
}
}
}
for( int i = N; i >= 1; i-- ){
for( int j = 1; j <= N; j++ ){
if( s[i][j] == '.' ){
dp[6][i][j] += 1 + dp[6][i+1][j-1];
dp[7][i][j] += 1 + dp[7][i+1][j];
}
}
}
for( int i = N; i >= 1; i-- ){
for( int j = N; j >= 1; j-- ){
if( s[i][j] == '.' ){
dp[8][i][j] += 1 + dp[8][i+1][j+1];
}
}
}
int ans = 0;
for( int i = 1; i <= N; i++ ){
for( int j = 1; j <= N; j++ ){
ans = max( ans, dp[1][i][j] + dp[3][i][j] - 1 );
ans = max( ans, dp[1][i][j] + dp[6][i][j] - 1 );
ans = max( ans, dp[1][i][j] + dp[8][i][j] - 1 );
ans = max( ans, dp[2][i][j] + dp[4][i][j] - 1 );
ans = max( ans, dp[2][i][j] + dp[5][i][j] - 1 );
ans = max( ans, dp[2][i][j] + dp[7][i][j] - 1 );
ans = max( ans, dp[3][i][j] + dp[1][i][j] - 1 );
ans = max( ans, dp[3][i][j] + dp[8][i][j] - 1 );
ans = max( ans, dp[3][i][j] + dp[6][i][j] - 1 );
ans = max( ans, dp[4][i][j] + dp[2][i][j] - 1 );
ans = max( ans, dp[4][i][j] + dp[5][i][j] - 1 );
ans = max( ans, dp[4][i][j] + dp[7][i][j] - 1 );
ans = max( ans, dp[5][i][j] + dp[2][i][j] - 1 );
ans = max( ans, dp[5][i][j] + dp[4][i][j] - 1 );
ans = max( ans, dp[5][i][j] + dp[7][i][j] - 1 );
ans = max( ans, dp[6][i][j] + dp[1][i][j] - 1 );
ans = max( ans, dp[6][i][j] + dp[8][i][j] - 1 );
ans = max( ans, dp[6][i][j] + dp[3][i][j] - 1 );
ans = max( ans, dp[7][i][j] + dp[4][i][j] - 1 );
ans = max( ans, dp[7][i][j] + dp[2][i][j] - 1 );
ans = max( ans, dp[7][i][j] + dp[5][i][j] - 1 );
ans = max( ans, dp[8][i][j] + dp[3][i][j] - 1 );
ans = max( ans, dp[8][i][j] + dp[6][i][j] - 1 );
ans = max( ans, dp[8][i][j] + dp[1][i][j] - 1 );
}
}
// cout << dp[4][1][3] << " " << dp[7][1][3] << endl;
printf( "%d\n", ans );
}
return 0;
}
1004.....又是爆搜。。。我队友写的。。。
附上队友代码
AC代码如下:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int MAX_N = (200 + 10);
const int inf = 0x3f3f3f3f;
struct Point {
int x, y;
Point() {}
Point(int _x, int _y) : x(_x), y(_y) {}
};
struct Node {
int x, y, kind, step;
vector<Point > V;
bool operator < (const Node &p) const
{
return p.step < step;
}
} st;
bool mark[MAX_N][MAX_N][11];
int Step[MAX_N][MAX_N][11];
char g[MAX_N][MAX_N];
int N, M, ans;
int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
bool Judge(const Node &p)
{
if (p.x < 0 || p.x >= N || p.y < 0 || p.y >= N) return false;
if (g[p.x][p.y] == '#') return false;
return true;
}
bool gao()
{
priority_queue<Node > que;
memset(mark, false, sizeof(mark));
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j){
for (int k = 0; k <= M; ++k) Step[i][j][k] = inf;
}
}
mark[st.x][st.y][st.kind] = true;
Step[st.x][st.y][st.kind] = 1;
que.push(st);
while (!que.empty()) {
Node q, p = que.top();
que.pop();
if (g[p.x][p.y] == 'T' && p.kind == M) { ans = p.step; return true; }
for (int i = 0; i < 4; ++i) {
q.x = p.x + dir[i][0];
q.y = p.y + dir[i][1];
q.step = p.step + 1;
q.kind = p.kind;
q.V = p.V;
if (Judge(q)) {
if (g[q.x][q.y] == 'S') {
bool found = false;
for (int j = 0; j < (int)q.V.size(); ++j) if (q.V[j].x == q.x && q.V[j].y == q.y) {
found = true;
break;
}
if (!found) ++q.step, q.V.push_back(Point(q.x, q.y));
} else if (g[q.x][q.y] >= '1' && g[q.x][q.y] <= '9') {
if (q.kind + 1 == g[q.x][q.y] - '0') {
++q.kind;
}
}
if (!mark[q.x][q.y][q.kind] || q.step < Step[q.x][q.y][q.kind]) {
mark[q.x][q.y][q.kind] = true;
Step[q.x][q.y][q.kind] = min(q.step, Step[q.x][q.y][q.kind]);
que.push(q);
}
}
}
}
return false;
}
int main()
{
while (cin >> N >> M) {
if (N == 0 && M == 0) break;
for (int i = 0; i < N; ++i) scanf("%s", g[i]);
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) if (g[i][j] == 'K') st.x = i, st.y = j, st.kind = st.step = 0, st.V.clear();
}
gao() ? printf("%d\n", ans) : puts("impossible");
}
return 0;
}