Polygon-funky

E. Polygon

给定一个数 n,生成一个 n×n 的一个全为 0 的初始矩阵,矩阵上方和左方均有一排炮台,矩阵的下边和右边是边界

炮台可以发射子弹,子弹只能直线行走,且遇到边界后会停止,遇到一个停止的子弹也会停止,子弹停止后的坐标里面的值记为 1

在任何时候,都不会有超过一门大炮在射击

输入

第一行一个整数 t,表示数据组数

对于每组数据:

第一行一个整数 n
接下来是 n个长度为 n 的行,由 0 和 1组成,表示输入矩阵

所有测试案例中矩阵的总面积不超过105

输出

存在YES,不存在NO

Example

Input

5
4
0010
0011
0000
0000
2
10
01
2
00
00
4
0101
1111
0101
0111
4
0100
1110
0101
0111

Output

YES
NO
YES
YES
NO

注意

第一个测试用例在声明中已经解释过了

第二个测试用例的答案是否定的,因为从任何大炮中飞出的单元格 ( 1,1 ) 中的 1 都会继续飞行

炮弹遇到边界后会停止,遇到一个停止的子弹也会停止,我们可以知道当下方和右方的地方都为 0 是不可能停下的

于是就可以检查矩阵中的元素,其下一个和右侧不能同时为 0

出现这种情况就不满足条件,则是 "NO"

[!NOTE]

本来不是这题的,其实昨天就已经写好了今天的,但是今天醒来发现居然和学长撞题了
,又挑了几题普及+的题发现一直不能完全过,红温了,于是在cf上找了一道1300的题
算了还是把昨天写的放一下尾页吧

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll gcd(ll p, ll q) {return ((p % q == 0)? q : gcd(q, p % q));}
ll lcm(ll p, ll q) {return p * q / gcd(p, q);}

void solve(){
    int n;cin >> n;
    int a[n][n];
    bool ans = true;
    for (int i = 0; i < n; ++i) 
    {
        string s;cin >> s;//转换为整数存储在数组中
        for (int j = 0; j < s.size(); j++) a[i][j] = s[j] - '0';   
    }
    for (int i = 0; i < n - 1; i++) 
    {
        for (int j = 0; j < n - 1; j++) 
        {
            if (a[i][j] == 1) {//当前元素是1,则检查下方和右方的元素
                if (a[i + 1][j] == 0 && a[i][j + 1] == 0) 
                {//如果下方和右方都是0,则NO
                    ans = false;
                    break;
                }
            }
        }
    }
    if (ans) cout << "YES" << endl;
    else cout << "NO" << endl;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);
    int t;cin >> t;while (t--) {
        solve();
    }
    return 0;
}

P1725 琪露诺

在幻想乡,琪露诺是以笨蛋闻名的冰之妖精 (baka)

某一天,琪露诺又在玩速冻青蛙,就是用冰把青蛙瞬间冻起来。但是这只青蛙比以往的要聪明许多,在琪露诺来之前就已经跑到了河的对岸。于是琪露诺决定到河岸去追青蛙

小河可以看作一列格子依次编号为 0N,琪露诺只能从编号小的格子移动到编号大的格子。而且琪露诺按照一种特殊的方式进行移动,当她在格子 i 时,她只移动到区间 [i+L,i+R] 中的任意一格。你问为什么她这么移动,这还不简单,因为她是笨蛋啊(baka)

每一个格子都有一个冰冻指数 Ai,编号为 0 的格子冰冻指数为0。当琪露诺停留在那一格时就可以得到那一格的冰冻指数 Ai。琪露诺希望能够在到达对岸时,获取最大的冰冻指数,这样她才能狠狠地教训那只青蛙

但是由于她实在是太笨了,所以她决定拜托你帮它决定怎样前进

开始时,琪露诺在编号$ 0 N$就算到达对岸

输入格式

第一行三个正整数N,L,R

第二行共 $N+1 i$个数表示编号为 i1 的格子的冰冻指数 Ai1

输出格式

一个整数,表示最大冰冻指数

样例

输入

5 2 3
0 12 3 11 7 -2

**输出 **

11

说明/提示

对于 60%的数据,N104

对于 100%的数据,N2×105103Ai1031LRN

数据保证最终答案不超过2e311

歌词大意:

小河为编号0从到N的格子序列,baka0号格出发,只能向编号更大的格子移动,且每次移动范围在当前格编号i[i+L,i+R] 区间内

每个格子有冰冻指数Ai0号格冰冻指数为0baka停留在某格可获取其冰冻指数

baka到达对岸(下一步的位置编号大于N)时能获得的最大冰冻指数

由题易知用线性dp,f[i]表示到第i个点为止所能获得的最大收益 则f[i]=a[i]+max(f[ir],...,f[il])

但是复杂度为O(n2),还是不能AC

因此我们需要好好优化一下~~❤❤❤

由标签可知主要可以用单调队列优化

(单调队列来解决的问题一般都是需要得到当前的某个范围内的最小值或最大值)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//const int N = 2e5 + 10;
ll gcd(ll p, ll q) {return ((p % q == 0)? q : gcd(q, p % q));}
ll lcm(ll p, ll q) {return p * q / gcd(p, q);}

void solve(){
	int n, l, r, baka = -INT_MIN;
    cin >> n >> l >> r;
    vector<int> a(n + 1),f(n + 1);
    deque<int> q;//双端队列
    //或者vector<int> q;
    for (int i = 0; i <= n; i++) 
    {
        cin >> a[i];
        f[i] = baka;//确保其他初始值足够小
    }
    f[0] = 0;//空区间的和为0,确保能正确累加子区间和
    for (int i = l; i <= n; i++) 
    {//移除不在窗口[i-r, i-l]内的元素
        while (!q.empty() && q.front() + r < i) 
        {
            q.pop_front();//或者q.erase(q.begin());
        }
        while (!q.empty() && f[q.back()] <= f[i - l]) 
        {//使头部始终是当前窗口内f值最大的索引(维护双端队列)
            q.pop_back();
        }
        q.push_back(i - l);///存入i-l到末尾
        f[i] = f[q.front()] + a[i];//以i结尾的最大子区间和
        if (i + r > n) baka = max(baka, f[i]);
    }
    cout << baka << endl;

}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);
    //int t;cin >> t;while (t--) {
        solve();
    //}
    return 0;
}



posted @   土木牢盖  阅读(42)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示