LL(1)

改进版:https://blog.youkuaiyun.com/qq_32067151/article/details/82795268

package phrase;
/*
 * 
 * 目前还存在的问题以及改进方法
 * 1:栈中连续终结符只能默认第二为非终结符
 * 解决办法:用循环进行排除
 * 2:对非法输入扫描串不能识别
 */
import java.util.Scanner;
/*@代表空
 
 //终结符
i+*()# 
//非终结符             
EeTtF
//LL(1)表
Te   n  n   Te   n  n
n   +Te  n   n    @  @
Ft  n   n   Ft   n  n
n   @   *Ft n    @  @
i   n   n  (E)   n  n
/*
正确匹配例子
i*i+i#
i+i*i#
//错误匹配例子
  i**i#
  //栈中匹配中结束 ,但是扫描串未扫描完
  i*i+i+i#
  //扫描串匹配完成,但是栈中还有存留
  i*i#
*/
public class phrase {
   //终结符串
   static String  final_sign=null;
   //非终结符串
   static String  Nfinal=null;
public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
///////////////////////////////////////////////
/*----------------初始化表---------------------
// ///////////////////////////////////////////*/
        //接受终结符
        System.out.println("请输入终结符号集合:");
        final_sign=sc.nextLine();
        //接受非终结符
        System.out.println("请输入非终结符号集合:");
            Nfinal=sc.nextLine();

        //根据终结符与非终结符的长度创建一个表      
        int h=Nfinal.length();
        int l=final_sign.length();
        String[][] Table=new String[h][l];
        System.out.println(Table.length);
        System.out.println(Table[0].length);
        System.out.println("请输入矩阵句型:");
        for (int i = 0; i < Table.length; i++) {            //行
for (int j = 0; j < Table[0].length; j++) {     //列
Table[i][j]=sc.next();
}
}
        for (String[] strings : Table) {
for (String string : strings) {
System.out.printf("%s\t",string);
}
System.out.println();
}
        //接受输入要扫描的字符串
        System.out.println("请输入你所要扫描的字符串:");
        String input_str=sc.next();
        sc.close();
       
/*/////////////////////////////////////////////////////////
//--------------------如下进行匹配------------------------/
/////////////////////////////////////////////////////////*/
        //构建栈
        char[] sign_stack=new char[10]; 
       
        //构建指针
        int top=1;           //指向栈顶
        int lr=0;            //指向扫描字符
       
        //初始化栈
        sign_stack[0]='#';
        sign_stack[1]=Nfinal.charAt(0);
       
        //表的行坐标
        int hang=0;
        int lie=0;
       
        //取得栈顶元素
        char stack_top;
        while(sign_stack[top]!='#'||input_str.charAt(lr)!='#') {
       
        stack_top=sign_stack[top];      //取出栈顶元素
       
                /*/////////////////////////////////////////////////
                 * 
                 *            问题存在区域
                 * 
                 */////////////////////////////////////////////////
       
        //---------------判断栈顶元素是否为终结符--------------
        if(!isNfinal(stack_top)) {                                     //是终结符   
        //与扫描串当前字符匹配 
        if(stack_top==input_str.charAt(lr)){                       //可以匹配
        lr++;     //进行下一个字符匹配
        sign_stack[top]='0';
        top--;    //弹出栈顶元素终结符
        stack_top=sign_stack[top];
        }else {                                                    //句型不匹配推出
        System.out.println("GGGG!!!");
        break;
        }
        }
        //---------------进行非终结符推导----------------------
       
        hang=Nfinal.indexOf(stack_top);                          //查找在表中的行位置
        lie=final_sign.indexOf(input_str.charAt(lr));            //查找在表中的列位置
        //将当前表中符号串与字符进行比较
        if(Table[hang][lie].equals("n")) {                       //1.如果没有匹配的
        System.out.println("GG!!");
        break;
        }else {
         if(Table[hang][lie].length()==1&&Table[hang][lie].charAt(0)==input_str.charAt(lr)) {  //如果终结符匹配成功将栈顶元素弹出,并且进行下一个字符匹配
            sign_stack[top]='0';                        //出栈
            top--;                                      //栈顶指针变化
                         lr++;                                       //扫描指针发生变化
                }else if(Table[hang][lie].equals("@")){              //如果存在是空@则弹出栈顶元素
                
                sign_stack[top]='0';
            top--;
               }else {                                              //否则将栈顶元素出栈并将推导式入栈
           for(int i=Table[hang][lie].length()-1;i>=0;i--) {
            //判断将要插入的字符是否为非终结符
           
               sign_stack[top]=Table[hang][lie].charAt(i);       
               top++;
           }
           top--;
           }
         }
         }
/*//////////////////////////////////////////////////////////////
 *                  判断匹配成功
 *//////////////////////////////////////////////////////////////
        if(sign_stack[top]=='#'&&input_str.charAt(lr)=='#')
         System.out.println("匹配成功!!!");
        else {
        System.out.println("出错位置:"+lr+1);
        }
       
       
       }
/*//////////////////////////////////////////////////////////////
 *                 判断字符是否为非终结符
 *//////////////////////////////////////////////////////////////
private static boolean isNfinal(char temp) {
for (int i = 0; i < Nfinal.length(); i++) {
if(temp==Nfinal.charAt(i)) return true;
}
return false;
}

 

}

#include <bits/stdc++.h> using namespace std; typedef long long ll; #define INF 0x7ffffff #define rep(i,s,t) for(register ll i = s;i <= t;++i) #define per(i,t,s) for(register ll i = t;i >= s;--i) const ll N = 1e5 + 5; const ll M = 5e5 + 5; ll n; ll m; ll q; ll ans = -INF; ll a[N] = {}; ll b[N] = {}; class segment_tree { private: struct node { ll l; ll r; ll maxn; ll minn; }; node t[M]; inline ll lson(ll p) { return p << 1; } inline ll rson(ll p) { return p << 1 | 1; } inline void push_up(ll p) { t[p].maxn = max(t[lson(p)].maxn,t[rson(p)].maxn); t[p].minn = min(t[lson(p)].minn,t[rson(p)].minn); } public: inline void build(ll p,ll l,ll r) { t[p].l = l; t[p].r = r; if(l == r) { t[p].maxn = 0; t[p].minn = 0; return; } ll mid = l + r >> 1; build(lson(p),l,mid); build(rson(p),mid + 1,r); push_up(p); } inline void update(ll p,ll x,ll k) { if(t[p].l == t[p].r) { t[p].maxn = k; t[p].minn = k; return; } ll mid = t[p].l + t[p].r >> 1; if(x <= mid) update(lson(p),x,k); else update(rson(p),x,k); push_up(p); } inline ll query_max(ll p,ll l,ll r) { if(l <= t[p].l && t[p].r <= r) return t[p].maxn; ll ans = -INF; ll mid = t[p].l + t[p].r >> 1; if(l <= mid) ans = max(ans,query_max(lson(p),l,r)); if(r > mid) ans = max(ans,query_max(rson(p),l,r)); return ans; } inline ll query_min(ll p,ll l,ll r) { if(l <= t[p].l && t[p].r <= r) return t[p].minn; ll ans = INF; ll mid = t[p].l + t[p].r >> 1; if(l <= mid) ans = min(ans,query_min(lson(p),l,r)); if(r > mid) ans = min(ans,query_min(rson(p),l,r)); return ans; } }; class dual_segment_tree { private: struct node { ll l; ll r; ll maxn = -INF; ll minn = INF; }; node t[M]; inline ll lson(ll p) { return p << 1; } inline ll rson(ll p) { return p << 1 | 1; } inline void push_up(ll p) { t[p].maxn = max(t[lson(p)].maxn,t[rson(p)].maxn); t[p].minn = min(t[lson(p)].minn,t[rson(p)].minn); } public: inline void build(ll p,ll l,ll r) { t[p].l = l; t[p].r = r; if(l == r) return; ll mid = l + r >> 1; build(lson(p),l,mid); build(rson(p),mid + 1,r); } inline void update(ll p,ll x,ll k,bool opt) { if(t[p].l == t[p].r) { if(opt) { t[p].maxn = -INF; t[p].minn = INF; } else { t[p].maxn = k; t[p].minn = k; } return; } ll mid = t[p].l + t[p].r >> 1; if(x <= mid) update(lson(p),x,k,opt); else update(rson(p),x,k,opt); push_up(p); } inline ll query_max(ll p,ll l,ll r) { if(l <= t[p].l && t[p].r <= r) return t[p].maxn; ll ans = -INF; ll mid = t[p].l + t[p].r >> 1; if(l <= mid) ans = max(ans,query_max(lson(p),l,r)); if(r > mid) ans = max(ans,query_max(rson(p),l,r)); return ans; } inline ll query_min(ll p,ll l,ll r) { if(l <= t[p].l && t[p].r <= r) return t[p].minn; ll ans = INF; ll mid = t[p].l + t[p].r >> 1; if(l <= mid) ans = min(ans,query_min(lson(p),l,r)); if(r > mid) ans = min(ans,query_min(rson(p),l,r)); return ans; } }; segment_tree t; dual_segment_tree pos; dual_segment_tree neg; inline ll read() { ll x = 0; ll y = 1; char c = getchar(); while(c < '0' || c > '9') { if(c == '-') y = -y; c = getchar(); } while(c >= '0' && c <= '9') { x = (x << 3) + (x << 1) + (c ^ '0'); c = getchar(); } return x * y; } inline void write(ll x) { if(x < 0) { putchar('-'); write(-x); return; } if(x > 9) write(x / 10); putchar(x % 10 + '0'); } int main() { n = read(); m = read(); q = read(); pos.build(1,1,n); neg.build(1,1,n); rep(i,1,n) { a[i] = read(); if(a[i] >= 0) { pos.update(1,i,a[i],false); neg.update(1,i,a[i],true); } else { pos.update(1,i,a[i],true); neg.update(1,i,a[i],false); } } rep(i,1,m) { b[i] = read(); t.update(1,i,b[i]); } rep(o,1,q) { ans = -INF; ll l1 = 0; ll r1 = 0; ll l2 = 0; ll r2 = 0; l1 = read(); r1 = read(); l2 = read(); r2 = read(); ll max_t = t.query_max(1,l2,r2); ll min_t = t.query_min(1,l2,r2); ll max_pos = pos.query_max(1,l1,r1); ll min_pos = pos.query_min(1,l1,r1); ll max_neg = neg.query_max(1,l1,r1); ll min_neg = neg.query_min(1,l1,r1); if(max_pos != -INF) ans = max(ans,max_pos * min_t); if(min_pos != INF) ans = max(ans,min_pos * min_t); if(max_neg != -INF) ans = max(ans,max_neg * max_t); if(min_neg != INF) ans = max(ans,min_neg * max_t); write(ans); putchar('\n'); } return 0; } #include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i, s, t) for (ll i = (s); i <= (t); ++i) #define per(i, t, s) for (ll i = (t); i >= (s); --i) #define debug if (0) const ll INF = 1e18 + 1; class DualSegmentTree { private: struct Node { ll l, r; ll mx, mi; }; vector<Node> t; const bool type; // 0-非负 1-负 inline ll lson(ll p) { return p << 1; } inline ll rson(ll p) { return p << 1 | 1; } void push_up(ll p) { t[p].mx = max(t[lson(p)].mx, t[rson(p)].mx); t[p].mi = min(t[lson(p)].mi, t[rson(p)].mi); } public: DualSegmentTree(ll n, bool _type) : type(_type) { t.resize(n << 2); build(1, 1, n); } void build(ll p, ll l, ll r) { t[p].l = l, t[p].r = r; t[p].mx = -INF; t[p].mi = INF; if (l == r) return; ll mid = (l + r) >> 1; build(lson(p), l, mid); build(rson(p), mid + 1, r); } void insert(ll p, ll pos, ll val, bool is_foreign) { if (t[p].l == t[p].r) { if (is_foreign) { t[p].mx = -INF; t[p].mi = INF; } else { t[p].mx = t[p].mi = val; } return; } ll mid = (t[p].l + t[p].r) >> 1; if (pos <= mid) insert(lson(p), pos, val, is_foreign); else insert(rson(p), pos, val, is_foreign); push_up(p); } ll query_max(ll p, ll L, ll R) { if (t[p].l >= L && t[p].r <= R) return t[p].mx; ll mid = (t[p].l + t[p].r) >> 1; ll res = -INF; if (L <= mid) res = max(res, query_max(lson(p), L, R)); if (R > mid) res = max(res, query_max(rson(p), L, R)); return res; } ll query_min(ll p, ll L, ll R) { if (t[p].l >= L && t[p].r <= R) return t[p].mi; ll mid = (t[p].l + t[p].r) >> 1; ll res = INF; if (L <= mid) res = min(res, query_min(lson(p), L, R)); if (R > mid) res = min(res, query_min(rson(p), L, R)); return res; } }; class SimpleSegmentTree { private: struct Node { ll l, r; ll mx, mi; }; vector<Node> t; inline ll lson(ll p) { return p << 1; } inline ll rson(ll p) { return p << 1 | 1; } void push_up(ll p) { t[p].mx = max(t[lson(p)].mx, t[rson(p)].mx); t[p].mi = min(t[lson(p)].mi, t[rson(p)].mi); } public: SimpleSegmentTree(ll n) { t.resize(n << 2); build(1, 1, n); } void build(ll p, ll l, ll r) { t[p].l = l, t[p].r = r; if (l == r) { t[p].mx = t[p].mi = 0; // 初始值需外部设置 return; } ll mid = (l + r) >> 1; build(lson(p), l, mid); build(rson(p), mid + 1, r); push_up(p); } void insert(ll p, ll pos, ll val) { if (t[p].l == t[p].r) { t[p].mx = t[p].mi = val; return; } ll mid = (t[p].l + t[p].r) >> 1; if (pos <= mid) insert(lson(p), pos, val); else insert(rson(p), pos, val); push_up(p); } ll query_max(ll p, ll L, ll R) { if (t[p].l >= L && t[p].r <= R) return t[p].mx; ll mid = (t[p].l + t[p].r) >> 1; ll res = -INF; if (L <= mid) res = max(res, query_max(lson(p), L, R)); if (R > mid) res = max(res, query_max(rson(p), L, R)); return res; } ll query_min(ll p, ll L, ll R) { if (t[p].l >= L && t[p].r <= R) return t[p].mi; ll mid = (t[p].l + t[p].r) >> 1; ll res = INF; if (L <= mid) res = min(res, query_min(lson(p), L, R)); if (R > mid) res = min(res, query_min(rson(p), L, R)); return res; } }; inline ll read() { ll x = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); } while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } ll a[100005], b[100005]; int main() { ll n = read(), m = read(), q = read(); DualSegmentTree pos_tr(n, 0); DualSegmentTree neg_tr(n, 1); rep(i, 1, n) { a[i] = read(); if (a[i] >= 0) { pos_tr.insert(1, i, a[i], false); neg_tr.insert(1, i, a[i], true); } else { neg_tr.insert(1, i, a[i], false); pos_tr.insert(1, i, a[i], true); } } SimpleSegmentTree b_tr(m); rep(i, 1, m) { b[i] = read(); b_tr.insert(1, i, b[i]); } while (q--) { ll l1 = read(), r1 = read(), l2 = read(), r2 = read(); ll maxz = pos_tr.query_max(1, l1, r1); ll minz = pos_tr.query_min(1, l1, r1); ll maxf = neg_tr.query_max(1, l1, r1); ll minf = neg_tr.query_min(1, l1, r1); ll maxb = b_tr.query_max(1, l2, r2); ll minb = b_tr.query_min(1, l2, r2); ll ans = -INF; if (maxz != -INF) ans = max(ans, maxz * minb); if (minz != INF) ans = max(ans, minz * minb); if (maxf != -INF) ans = max(ans, maxf * maxb); if (minf != INF) ans = max(ans, minf * maxb); printf("%lld\n", ans); } return 0; } 请针对洛谷P8818策略游戏,指出上述两段代码的区别,并精确保留第一段代码风格修正第一段代码
最新发布
08-15
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值