Codeforces Good Bye 2016 D 模拟搜索?

给出烟花的爆炸方式和爆炸次数 问最后有多少个格子会被炸到

如果dfs的话会超时...

利用模拟每一层来搜索..?

思想就是一开始有一个爆炸点向上 然后模拟完第一段 会产生一个爆炸点 朝两个方向 就用vector来存 每一层都处理一段的爆炸点 产生新一段的爆炸点

因为5*30=150 所以图建300就可以了 300 * 300 * 30的时间复杂度

但是常数很大..不过无所谓啦..

需要注意的是 一个爆炸点可能会同时出现两次朝同一个方向开始爆炸的烟花 这个是没有意义的 所以拿一个数组来记录 不然最后会产生很多情况

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<map>
#include<string>
#include<vector>
#include<queue>
#include<iostream>
using namespace std;
#define L long long
int a[35];
int n;
bool vis[405][405];
int res ;
/// 1 2 3 4 5 6 7 8
int dx[8] = {-1,-1,0,1,1,1,0,-1};
int dy[8] = {0,1,1,1,0,-1,-1,-1};
vector<int >q[405][405];
vector<int >z[405][405];
bool cz[405][405][8];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    memset(vis,true,sizeof(vis));
    for(int i = 0;i<=402;i++){
        for(int j = 0;j<= 402;j++){
            q[i][j].clear();
        }
    }
    for(int i = 0;i<=402;i++){
        for(int j = 0;j<= 402;j++){
            z[i][j].clear();
        }
    }
    res = 0;
    q[200][200].push_back(0);
    memset(cz,false,sizeof(cz));
    for(int w = 1;w <= n ;w ++){
        for(int i = 1;i<=400;i++){
            for(int j = 1;j<=400;j++){
                for(int l = 0; l< q[i][j].size();l ++){
                    for(int k = 1;k<=a[w];k++){
                        if(vis[k*dx[q[i][j][l]] + i][k*dy[q[i][j][l]] + j] == true)
                            vis[k*dx[q[i][j][l]] + i][k*dy[q[i][j][l]] + j] = false,res ++ ;
                    }
                    int fx1 = q[i][j][l] + 1; fx1 += 8; fx1 %= 8;
                    int fx2 = q[i][j][l] - 1; fx2 += 8; fx2 %= 8;
                    if(cz[a[w]*dx[q[i][j][l]] + i][a[w]*dy[q[i][j][l]] + j][fx1] == false)
                        z[a[w]*dx[q[i][j][l]] + i][a[w]*dy[q[i][j][l]] + j].push_back(fx1),cz[a[w]*dx[q[i][j][l]] + i][a[w]*dy[q[i][j][l]] + j][fx1] = true;
                    if(cz[a[w]*dx[q[i][j][l]] + i][a[w]*dy[q[i][j][l]] + j][fx2] == false)
                        z[a[w]*dx[q[i][j][l]] + i][a[w]*dy[q[i][j][l]] + j].push_back(fx2),cz[a[w]*dx[q[i][j][l]] + i][a[w]*dy[q[i][j][l]] + j][fx2] = true;
                }
                q[i][j].clear();
            }
        }
        for(int i = 1;i<=400;i++){
            for(int j = 1 ;j<=400;j++){
                for(int l = 0;l < z[i][j].size();l ++){
                    q[i][j].push_back(z[i][j][l]);
                }
                z[i][j].clear();
            }
        }
        memset(cz, false, sizeof(cz));
    }
    printf("%d\n",res);
}

  

时间: 2024-12-25 06:19:48

Codeforces Good Bye 2016 D 模拟搜索?的相关文章

codeforces Good bye 2016 E 线段树维护dp区间合并

题目大意:给你一个字符串,范围为'0'~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问,最少删除多少个字符,使得串中符合ugly串? 思路:定义dp(i, j),其中i=5,j=5,因为只需要删除2016当中其中一个即可,所以一共所需要删除的字符和需要的字符为20176,因此i和j只要5就够了. 然后转移就是dp(i,i) = 0, 如果说区间大小为1的话,那么如果是2017中的一个,那么就是dp(pos, pos+1) = 0, dp(pos,pos) =

Codeforces Good Bye 2016 E. New Year and Old Subsequence

传送门 题意: 给出一个长度为\(n\)的串,现在有\(q\)个询问,每个询问是一个区间\([l,r]\),要回答在区间\([l,r]\)中,最少需要删多少个数,满足区间中包含\(2017\)的子序列而不包含\(2016\)的子序列. 思路: 先不考虑多个询问,那么这个问题区间\(dp\)可以解决,状态定义中要附加状态转移的代价. 比如当前数字为\(7\),那么显然从状态\(201\)转移过来需要\(0\)的花费:但如果不要\(7\),那么从状态\(201\)到状态\(201\)则需要\(1\)

Codeforces 475C Kamal-ol-molk&#39;s Painting 模拟

题目链接:点击打开链接 题意:给定n*m的矩阵 X代表有色 .代表无色 用一个x*y的矩阵形刷子去涂色. 刷子每次可以→或↓移动任意步. 若能够染出给定的矩阵,则输出最小的刷子的面积 若不能输出-1 思路: 先找到连续最小的x,y 因为至少一个边界和x或y相等,所以枚举(x,i) 和 (i,y)就可以了. #pragma comment(linker, "/STACK:102400000,102400000") #include <stdio.h> #include <

poj 3087 Shuffle&#39;m Up (模拟搜索)

Shuffle'm Up Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5953   Accepted: 2796 Description A common pastime for poker players at a poker table is to shuffle stacks of chips. Shuffling chips is performed by starting with two stacks of

模拟 --- 搜索模拟

Robot Motion Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 10130   Accepted: 4932 Description A robot has been programmed to follow the instructions in its path. Instructions for the next direction the robot is to move are laid down in

Codeforces 30D King&#39;s Problem? 模拟

首先将n个点排序,找出排序后的K,然后分情况讨论. 当 k == n+1时,显然是 k->1->n || k->n->1这两种的较小值,因为三角形的两边之和大于第三边. 当1 <= k && k <= n 时: 1 , k -> 1 -> n+1 -> k+1 ->n  ||  k -> n -> n+1 -> k-1 -> 1,当k+1 || k-1 不存在时将对应步骤忽略. 2 , k - > 1

【BZOJ4524】[Cqoi2016]伪光滑数 堆(模拟搜索)

[BZOJ4524][Cqoi2016]伪光滑数 Description 若一个大于1的整数M的质因数分解有k项,其最大的质因子为Ak,并且满足Ak^K<=N,Ak<128,我们就称整数M为N-伪光滑数.现在给出N,求所有整数中,第K大的N-伪光滑数. Input 只有一行,为用空格隔开的整数N和K 2 ≤ N ≤ 10^18, 1 ≤ K ≤ 800000,保证至少有 K 个满足要求的数 Output 只有一行,为一个整数,表示答案. Sample Input 12345 20 Sample

Codeforces 747C:Servers(模拟)

http://codeforces.com/problemset/problem/747/C 题意:有n台机器,q个操作.每次操作从ti时间开始,需要ki台机器,花费di的时间.每次选择机器从小到大开始,如果可以完成任务,那么输出id总和,否则输出-1. 思路:简单的模拟,注意如果不能完成任务,那么ser数组是不能更新的. 1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #includ

CodeForces 670 A. Holidays(模拟)

Description On the planet Mars a year lasts exactly n days (there are no leap years on Mars). But Martians have the same weeks as earthlings — 5 work days and then 2 days off. Your task is to determine the minimum possible and the maximum possible nu