標籤:blog http io os 使用 ar for 檔案 資料
https://vijos.org/p/1765
這題用白書的方法是n^2的,所以我tle了一個點。。sad。
我稍微最佳化了一下。
這個題給我最大的感受不是這個題本身,而是我感受到了自己思考以後並認真查錯一次提交獲得這麼高分的感受。
做題一定要認真、仔細。
寫這些題最重要的就是仔細,一些細節方面沒處理好,那麼就會掛了,而陷入調試的泥潭。
想想我以前寫的程式,哪個不是這樣呢?
首先一定要有個大概的架構了且自己反覆論證這樣做是正確的(不考慮滿分的情況下,可以充當暴力以便對拍和騙分)
一定要反覆論證!
然後是在自己寫的時候一定要專心,且一定要跟著架構走,如果發現自己之前想的是錯的,一定先離開鍵盤,仔細的再想一遍。
當寫完是否龐大的碼量後,一定要靜態查錯,無疑是幾個地方:變數名、數組、邏輯、sb錯,且一定要反覆驗證自己代碼的邏輯正確性。
之後才測範例。
一般是直接過的。
如果不過那麼不要陷入調試的泥潭,一定要重新看一下哪裡會錯,哪裡可能會錯。然後對應的在那裡調試,而對應的在那裡調試那麼就要看自己代碼的分塊性了,分塊得好那麼就易於調試。
好了。。
以後就這樣,不要著急,要知道這是自己在戰鬥,只是為瞭解決問題,而不是一昧地去追求代碼的美觀,而是正確性。
#include <cstdio>#include <cstring>#include <cmath>#include <string>#include <iostream>#include <algorithm>#include <queue>#include <map>#include <cassert>using namespace std;#define rep(i, n) for(int i=0; i<(n); ++i)#define for1(i,a,n) for(int i=(a);i<=(n);++i)#define for2(i,a,n) for(int i=(a);i<(n);++i)#define for3(i,a,n) for(int i=(a);i>=(n);--i)#define for4(i,a,n) for(int i=(a);i>(n);--i)#define CC(i,a) memset(i,a,sizeof(i))#define read(a) a=getint()#define print(a) printf("%d", a)#define dbg(x) cout << (#x) << " = " << (x) << endl#define printarr2(a, b, c) for1(_, 1, b) { for1(__, 1, c) cout << a[_][__]; cout << endl; }#define printarr1(a, b) for1(_, 1, b) cout << a[_] << ‘\t‘; cout << endlinline const int getint() { int r=0, k=1; char c=getchar(); for(; c<‘0‘||c>‘9‘; c=getchar()) if(c==‘-‘) k=-1; for(; c>=‘0‘&&c<=‘9‘; c=getchar()) r=r*10+c-‘0‘; return k*r; }inline const int max(const int &a, const int &b) { return a>b?a:b; }inline const int min(const int &a, const int &b) { return a<b?a:b; }map<string, int> mp;typedef long long ll;const int N=105, M=100005;const ll eps=1e9;int n, m, ID, a[N], flag, tot, db;char s[15];struct node { node *l, *r; bool f, opt; int s; node() { l=r=NULL; f=opt=0; s=0; } }*root=NULL;struct dat { int s; bool f, opt; dat() { s=0; f=opt=0; } }b[M];int getid(char *st, int len) {string s(st, len);if(mp[s]) return mp[s];mp[s]=++ID;return ID;}ll cal(node *x) {if(x==NULL || flag) return 0;if(!x->opt) {if(x->f) return a[x->s];return x->s;}ll l=cal(x->l), r=cal(x->r), ret=0;int opt=x->s;if(flag) return 0;if(opt==‘/‘ && r==0) { flag=1; return 0; }if(opt==‘+‘) ret=l+r;if(opt==‘-‘) ret=l-r;if(opt==‘*‘) ret=l*r;if(opt==‘/‘) ret=l/r;if(abs(ret)>eps) { flag=1; return 0; }return ret;}void build(int l, int r, node *&x) {// if(db>1) return;// ++db;// assert(l<=r);if(l==r) {x=new node();x->f=b[l].f;x->s=b[l].s;return;}int p=0, c1=-1, c2=-1;for1(i, l, r) {if(!b[i].opt) continue;if(b[i].s==‘(‘) ++p;else if(b[i].s==‘)‘) --p;else if(!p && (b[i].s==‘+‘ || b[i].s==‘-‘)) c1=i;else if(!p && (b[i].s==‘*‘ || b[i].s==‘/‘)) c2=i;}if(c1==-1) c1=c2;if(c1==-1) { build(l+1, r-1, x); return; }//puts("here"); dbg(c1);x=new node();build(l, c1-1, x->l); build(c1+1, r, x->r);x->opt=1;x->s=b[c1].s;}int main() {read(n); read(m);for1(i, 1, n) {scanf("%s", s);getid(s, strlen(s));}char c=getchar(); while(c==‘\n‘||c==‘\r‘||c==‘ ‘) c=getchar();while(c!=‘\n‘) {if(c>=‘0‘ && c<=‘9‘) {int r=0;while(c>=‘0‘ && c<=‘9‘) r=r*10+c-‘0‘, c=getchar();b[++tot].s=r;}else if((c>=‘A‘ && c<=‘Z‘) || (c>=‘a‘ && c<=‘z‘)) {int len=0;while((c>=‘A‘ && c<=‘Z‘) || (c>=‘a‘ && c<=‘z‘)) s[len++]=c, c=getchar();s[len]=‘\0‘;b[++tot].s=getid(s, len);b[tot].f=1;}else if(c!=‘\n‘) {b[++tot].opt=1;b[tot].s=c;c=getchar();}}build(1, tot, root);while(m--) {for1(i, 1, n) read(a[i]);flag=0;int ans=cal(root);if(flag) puts("Error!");else printf("%d\n", ans);}return 0;}
描述
計算機是生活中的常用計算工具,可以用來計算各種各樣的代數式的值。不過它是有些缺點的,一個主要的問題是它只支援常量的運算。對於同樣形式的代數式,僅僅是因為常量的不同就需要重新輸入一遍。
程式員們則可以使用進階語言中的運算式求值。在Pascal/C++語言中,運算式是一個很基礎的概念。運算式中可以出現變數、常量、運算子、括弧,甚至各種各樣的函數。
這裡我們僅考慮這樣的運算式:它由52個大小寫英文字母、數字‘0‘~‘9‘,和’(’、’)’、’+’、’-’、’*’、’/‘這些符號組成。每 個運算子都只執行雙目運算子的功能,即它的左右兩側都必須是可計算的量。特別的,這裡使用‘/‘符號表示整除。而連續的英文字母組成的單詞則表示變數名, 且變數名僅由字母組成。為了簡化問題,運算式中的常量均為絕對值不超過10^9的自然數,且無前置0。運算式的計算方法和在來源程式中是一樣的,即小括弧優 先級最高、而‘*‘、‘/‘運算子優先順序高於‘+‘、‘-’運算子,同一優先順序從左至右按順序計算。
你的任務,就是對於一個給定的運算式,實現它的計算功能。我們將聲明N個變數,並在運算式中引用這些變數。然後給出T組資料。每組資料都是N個變數的一組取值。你需要對每組資料計算此時運算式的傳回值。
格式輸入格式
輸入檔案的第一行包括兩個整數N, T,依次表示運算式中引用的變數的數目,以及N個變數的需要計算的取值組數。
接下來N行,每行一個由英文字母組成的字串,依次表示每個變數名。
接下來一行,一個字串,表示運算式的內容。
接下來T行,每行N個整數,依次表示每個變數這時的取值。
輸出格式
輸出檔案包括T行,第i行表示N個變數取輸入的第i組數值時運算式的答案。
如果在運算過程中出現整數被0除,或者運算過程的中間結果的絕對值大於10^9,輸出”Error!”;否則輸出一個整數,表示運算結果。運算的中間結果指從左至右按優先順序順序計算時得到的每個數值。
範例1範例輸入1[複製]
2 3xtotal1+(total/x)1 32 1550 0
範例輸出1[複製]
478Error!
限制
1s
提示
20%的資料滿足,運算式中沒有小括弧。
另外20%的資料滿足,運算式中沒有加法或減法運算。
另外20%的資料滿足,運算式中沒有乘法或除法運算。
80%的資料(包括上述在內)滿足,運算式的長度不超過100。
100%的資料滿足,1 <= N <= 100,1 <= T <= 10,變數名長度不超過10,運算式長度不超過100,000。變數的取值和運算式中的常量是絕對值不超過10^9的自然數。所有變數名互不相同。
【vijos】1765 Caculator(代碼題)