離線賽總結2
阿新 • • 發佈:2021-10-05
啊 真的掛了 csp再掛就不行了啊
現在普及組的題都掛不到1=了
不能頹廢qaq
T1 [NOIP2013 普及組] 表示式求值
https://www.luogu.com.cn/problem/P1981
qaq 炸了 分炸沒了
因為前幾天寫了個表示式的題目就轉了字尾表示式求
真香了 char cnt= 0
還tm的是錯過的地方
#include <bits/stdc++.h> using namespace std; #define int long long #define Mod 10000 const int N= 1000005; //注意題目中的資料範圍是 表示式中加法運算子和乘法運算子的總數≤100000 但是真實情況的話還有數字 struct Node { int val; int is; }; int num[N], top; Node fu[N]; int tot; char ans[N]; int cnt; //char cnt qaq update 2021.10.5 已更正 signed main() { string s; cin>> s; for(int i=0; i<s.size(); i++) { if(s[i]== '*') ans[++ cnt]= s[i]; if(s[i]== '+') { while(ans[cnt]== '*') fu[++ tot].val= ans[cnt-- ], fu[tot].is= 1; ans[++ cnt]= '+'; } if(s[i]>= '0'&& s[i]<= '9') { int x= 0; while(s[i]>= '0'&& s[i]<= '9') x= (x* 10+ s[i]- '0')% Mod, i++; i-- ; fu[++ tot].val= x; } } while(cnt) fu[++ tot].val= ans[cnt-- ], fu[tot].is= 1; //轉字尾表示式 for(int i=1; i<=tot; i++) { if(fu[i].is== 0) num[++ top]= fu[i].val; else { int a= num[top-- ]; int b= num[top-- ]; if(fu[i].val== 43) num[++ top]= (a+ b)% Mod; else num[++ top]= (a* b)% Mod; } } //直接求值 cout<< num[1]% Mod<< endl; return 0; } //我可能是最麻煩的方法了 其實這題並不用那麼多 直接能乘就乘 能加就加好了
[NOIP2013 普及組] 小朋友的數字
https://www.luogu.com.cn/problem/P1982
小朋友的題都不會做了啊
怎麼說 自己坑自己?
考場上發現了會爆long long
然後作繭自縛 寫得不對???
原來有80pts的直接掛掉了
好在寫了個50pts的部分分
80pts (會爆long long
) 雖然寫的是P50
但有80pts
struct P50 { int a[N], f[N], t[N], h[N]; void solve() { for(int i=1; i<=n; i++) scanf("%lld", &a[i]); f[1]= a[1], t[1]= a[1]; for(int i=2; i<=n; i++) { f[i]= max(f[i- 1]+ a[i], a[i]); t[i]= max(t[i- 1], f[i]); } //dp求最大連續欄位和 其實t陣列就是個擺設, f陣列也沒啥用 h[1]= t[1]; int maxn= -INF; maxn= max(maxn, h[1]+ t[1]); for(int i=2; i<=n; i++) { h[i]= maxn; maxn= max(maxn, h[i]+ t[i]); } maxn= -INF; for(int i=1; i<=n; i++) maxn= max(maxn, h[i]); //模擬題 if(maxn< 0) { cout<< '-'; maxn= abs(maxn); } //聽說還有-0什麼的 不過沒卡 cout<< maxn% p<< endl; } }P50;
發現要寫高精 懶得寫 怎麼辦呢 錯誤的程式碼:
//其實可以發現就是上面的程式碼加上兩個函式2333 //不要懷疑 因為我就是這樣改的 #include <bits/stdc++.h> using namespace std; #define int long long #define INF (int)1e18 const int N= 1000005; struct Node { int s; int y; }a[N], f[N], t[N], h[N]; int n, p; Node add(Node a, Node b) { Node c; c.s= a.s+ b.s; c.y= a.y+ b.y; if(c.y/ p!= 0) c.s+= c.y/ p, c.y%= p; return c; } Node Max(Node a, Node b) { if(a.s> b.s) return a; else if(a.s< b.s) return b; else if(a.y> b.y) return a; else return b; } signed main() { cin>> n>> p; for(int i=1; i<=n; i++) { int x; scanf("%lld", &x); a[i].s= x/ p; a[i].y= x% p; } f[1]= a[1], t[1]= a[1]; for(int i=2; i<=n; i++) { f[i]= Max(add(f[i- 1], a[i]), a[i]); t[i]= Max(t[i- 1], f[i]); } h[1]= t[1]; Node maxn; maxn.s= -INF; maxn= Max(maxn, add(h[1], t[1])); for(int i=2; i<=n; i++) { h[i]= maxn; maxn= Max(maxn, add(h[i], t[i])); } maxn.s= -INF; for(int i=1; i<=n; i++) maxn= Max(maxn, h[i]); if(maxn.y< 0) { cout<< '-'; maxn.y= abs(maxn.y); } cout<< maxn.y% p<< endl; return 0; }
這是考場上部分程式碼 剩下的因為太亂和原始碼丟失就不放了
這是錯的 20pts 為什麼?
看起來很有道理啊
add太草率了
Node add(Node a, Node b)
{
Node c; c.s= a.s+ b.s;
c.y= a.y+ b.y; //他炸掉了
//In this way
if(c.s>= 0&& c.y>= p) c.s+= c.y/ p, c.y= c.y% p; //如果餘數同符號 一切都好
if(c.s<= 0&& c.y<= -p) c.s+= c.y/ p, c.y= c.y% p;
if(c.s> 0&& c.y< 0) c.s-- , c.y+= p; //不然我們不能直接搞 不可能a*p+b然後b是負的吧
if(c.s< 0&& c.y>= p) c.s++ , c.y-= p;
return c;
}
莫名其妙地Accept了
還有另外一種寫法 智商什麼的吊打高精度
不過這種高精度法也可以應用什麼的 用於小的高精度 100位什麼的不要找我啊qaq
未來可期。