180 条题解
-
7hack_leo LV 8 @ 2018-09-04 04:55:21
标准的表达式求值,代入法双栈即可
#include <iostream> #include <stack> #include <string> #include <sstream> #include <regex> #include <map> #include <cctype> #include <cmath> using namespace std; map<string,int> prio{ {"+",1}, {"-",1}, {"*",2}, {"/",2}, {"^",3}, {"(",4}, }; typedef long long ll; ll qpow(ll a,ll b){ ll ret=1; for(ll s=a;b;b>>=1u,s*=s) if(b&1u) ret*=s; return ret; } #define sigop(op) {#op,[](ll a,ll b){return a op b;}} map<string,function<ll (ll,ll)>> opr{ sigop(+), sigop(-), sigop(*), sigop(/), {"^",qpow} }; #undef sigop ll eval (string const& exp,ll x); int main() { string s0; int n; getline(cin,s0); cin>>n; cin.get(); for (int i=0;i<n;++i){ string s; getline(cin,s); bool flag=true; for(ll a=0;a<=10 && flag;++a) flag = eval(s,a) == eval(s0,a); if(flag) cout<<char('A'+i); } return 0; } template<typename T> T operator-- (stack<T>& s,int){ T ret=s.top(); s.pop(); return ret; } ll eval (string const& e,ll x) { stack<ll> ons; stack<string> ops; stringstream exp(regex_replace(regex_replace(e, regex(" "), ""), regex("([+/*()^-])"), " $1 ")); ll a; for (string s; exp >> s;) if (s == "a") ons.push(x); else if (stringstream(s) >> a) ons.push(a); else if (s == ")") for (string op; (op = ops--) != "(";) ons.push(opr[op](ons--, ons--)); else { while (!ops.empty() && ops.top() != "(" && prio[s] <= prio[ops.top()]) ons.push(opr[ops--](ons--, ons--)); ops.push(s); } while (ons.size() != 1) ons.push(opr[ops--](ons--, ons--)); return ons.top(); }
-
62013-09-03 19:34:47@
这题考的是字符串处理,然而十分繁琐,需要一定的技巧,还要十分注重细节
###算法
二分法——不断地寻找当前优先级最低的运算符,然后以它为中心将算式分成两段递归计算。
带入求值——因为要用多项式乘法对算式进行展开计算的话,不仅程序冗长繁琐,而且程序执行效率也十分低下。由于OI比赛的题目只有十组测试点,而且是按点得分,所以我们可以考虑用具体数字带入a求表达式的值来判断。为了减少误差,必须多取几个值。###细节问题
1. 如果带入整数,由于幂指数很高,所以有上溢的风险,必须加上取模,当然这是建立在对模算术熟悉的基础上。在这里笔者带入的是小浮点数,可以巧妙地避免溢出。
1. 带入小数就产生了如何比较两个小数相等的问题。小数大小不能用等号直接比较,这应该属于常识了。而常用的方法(比较差是否小于eps,eps一般去10的-6次到10的-9次不等),在这数量级悬殊的数字比较上也无能为力。所以我们可以先比较它们的数量级(log10的值)是否相同,再去比较值。然而这种方法实测时误差不小,请尽量少在别的题目中使用。
1. 题目中的表达式可能会出现多括号、少括号的情况,必须自己把括号补上。
1. 此题的读入也十分猥琐。由于空格的存在所以不能用scanf直接读取了,C++必须gets\fgets\getline,然后自己慢慢处理吧……###标程
#include <cstdio>
#include <cstring>
#include <cmath>double A; // 代表用来替代a的值
class expr
{
public:
char s[100],ts[100];
double getnum(int l,int r) // 获取数字
{
int i,x=0;
for (i=l;i<=r;i++)
x=x*10+(int)s[i]-48;
return (double)x;
}
double calc(int l,int r) // 计算从l到r的表达式的值
{
int i,k;
for (i=r,k=0;i>=l;i--) // 从优先级最低的加减号开始
{
if (k==0)
{
if (s[i]=='+')
return calc(l,i-1)+calc(i+1,r);
else if (s[i]=='-')
return calc(l,i-1)-calc(i+1,r);
}
if (s[i]=='(') k++;
else if (s[i]==')') k--;
}
for (i=r,k=0;i>=l;i--) // 处理乘号
{
if (k==0)
if (s[i]=='*')
return calc(l,i-1)*calc(i+1,r);
if (s[i]=='(') k++;
else if (s[i]==')') k--;
}
for (i=r,k=0;i>=l;i--) // 处理乘方
{
if (k==0)
if (s[i]=='^')
return pow(calc(l,i-1),calc(i+1,r));
if (s[i]=='(') k++;
else if (s[i]==')') k--;
}
if (s[l]=='('&&s[r]==')') // 处理括号
return calc(l+1,r-1);
if (l==r&&s[l]=='a') // 用A替代字母a的值
return A;
else
return getnum(l,r);
}
void scan() // 读入字符串并进行预处理
{
int i,j,k;
memset(ts,0,sizeof(ts));
memset(s,0,sizeof(s));
fgets(ts,sizeof(ts),stdin);
for (i=0,j=0,k=0;i<strlen(ts);i++)
if (ts[i]!=' '&&ts[i]!='\n') // 过滤空格和fgets读到的换行符
{
if (ts[i]=='('&&ts[i-1]==')') // 在两个相邻的括号之间添加乘号
s[j++]='*';
else if (ts[i]=='a'&&ts[i-1]>='0'&&ts[i-1]<='9') // 在a与它的系数之间添加乘号
s[j++]='*';
if (ts[i]=='(') k++;
else if (ts[i]==')') k--; // 统计括号数目
s[j++]=ts[i];
}
if (k>0) while (k--) s[j++]=')'; // 如果左括号多了,补充右括号
else if (k<0) // 如果有括号多了,补充左括号(这里用的方法很低效,应该还有更好的方案)
{
memset(ts,0,sizeof(ts)); j=0;
while (k++) ts[j++]='(';
strcat(ts,s);
memset(s,0,sizeof(s));
strcpy(s,ts);
}
}
double work() // 计算表达式的值
{
return calc(0,strlen(s)-1);
}
};bool cmp(double a,double b) // 比较两个浮点数是否相等(这个方法误差其实很大)
{
int x,y;
double r;
x=(int)log10(a)+1;y=(int)log10(b)+1;
if (x!=y) return false;
r=pow(10,x-12);
if (fabs(a-b)>r) return false;
return true;
}double P1,P2,P3,Q1,Q2,Q3;
int N,i;
expr S;
char ss[100];int main()
{
S.scan();
A=0.7; P1=S.work();
A=1.4; P2=S.work();
A=2.1; P3=S.work();
fgets(ss,sizeof(ss),stdin);
sscanf(ss,"%d",&N); // 读入N
for (i=1;i<=N;i++)
{
S.scan();
A=0.7; Q1=S.work();
A=1.4; Q2=S.work();
A=2.1; Q3=S.work();
if (cmp(P1,Q1)&&cmp(P2,Q2)&&cmp(P3,Q3))
printf("%c",(char)(64+i));
}
} -
32021-08-21 21:14:34@
#include<bits/stdc++.h> using namespace std; const long long mod=1e11+7; const int mxn=10010; int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } return x*f; } string s1,s2; char st[mxn];int top=0; long long num[mxn];int ntop=0; int cmp(char ch){ if(!top || st[top]=='(') return 0; if(st[top]=='^') return 1; if(ch=='^') return 0; if(st[top]=='*') return 1; if(ch=='*') return 0; return 1; } int pp(){ switch(st[top]){ case '(':{ top--; return 1; break; } case '+':{ long long n1=num[ntop--]; long long n2=num[ntop--]; num[++ntop]=n1+n2; break; } case '-':{ long long n1=num[ntop--]; long long n2=num[ntop--]; num[++ntop]=n2-n1; break; } case '*':{ long long n1=num[ntop--]; long long n2=num[ntop--]; num[++ntop]=n2*n1; break; } case '^':{ long long n1=num[ntop--]; long long n2=num[ntop--]; long long bas=1; for(int j=1;j<=n1;j++) bas=(bas*n2); num[++ntop]=bas; break; } } top--; return 0; } long long clc(string s,int tp){ top=ntop=0; memset(num,0,sizeof num); memset(st,0,sizeof st); int len=s.length(); int i,j; for(i=0;i<len;i++){ if(s[i]==' ') continue; if(s[i]=='('){ st[++top]='('; continue; } if(s[i]=='a'){ num[++ntop]=tp; continue; } if(s[i]>='0' && s[i]<='9') { int x=0; while(s[i]>='0' && s[i]<='9'){ x=x*10+s[i]-'0'; i++; } i--; num[++ntop]=x; continue; } if(s[i]==')'){ if(top==1 && i!=len-1)i++; while(1) if(pp()) break; continue; } while(cmp(s[i])) pp(); st[++top]=s[i]; } while(top>0){pp();} return num[1]; } int main(){ int i,j; getline(cin,s1); s1='('+s1+')'; int n; cin>>n; getline(cin,s2); for(i=0;i<n;++i){ getline(cin,s2); s2='('+s2+')'; bool flag=1; for(j=5;j<=11;j++){ if(clc(s1,j*7+3)!=clc(s2,j*7+3)){ flag=0; break; } } if(flag) printf("%c",i+'A'); } return 0; }
-
22014-08-08 16:33:24@
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
struct expr
{
char s[100],t[100];
int len;
double getnum(int l,int r)
{
int ret=0;
for(int i=l;i<=r;i++)
ret=ret*10+(s[i]-'0');
return(double)ret;
}
double calc(int A,int l,int r)
{
for(int k=0,i=r;i>=l;i--)
{
if(k==0)
{
if(s[i]=='+')
return calc(A,l,i-1)+calc(A,i+1,r);
if(s[i]=='-')
return calc(A,l,i-1)-calc(A,i+1,r);
}
if(s[i]==')')
k++;
if(s[i]=='(')
k--;
}
for(int k=0,i=r;i>=l;i--)
{
if(k==0&&s[i]=='*')
return calc(A,l,i-1)*calc(A,i+1,r);
if(s[i]==')')
k++;
if(s[i]=='(')
k--;
}
for(int k=0,i=r;i>=l;i--)
{
if(k==0&&s[i]=='^')
return pow(calc(A,l,i-1),calc(A,i+1,r));
if(s[i]==')')
k++;
if(s[i]=='(')
k--;
}
if(s[l]=='('&&s[r]==')')
return calc(A,l+1,r-1);
if(l==r&&s[l]=='a')
return A;
return getnum(l,r);
}
double work(int A)
{
return calc(A,0,len-1);
}
void scan()
{
memset(s,0,sizeof(s));
memset(t,0,sizeof(t));
len=0;
fgets(t,sizeof(t),stdin);
for(int i=0,l=strlen(t);i<l;i++)
if(t[i]!=' '&&t[i]!='\n')
s[len++]=t[i];
}
}S;
double P1=0.6450,P2=2.9970,P3=1.4250,A1,A2,A3,B1,B2,B3;
bool e(double x,double y)
{
int l1=(int)log10(x)+1,l2=(int)log10(y)+1;
if(l1!=l2)
return 0;
double r=pow(10.00,abs(l1)-10.00);
if(fabs(x-y)<r)
return 1;
return 0;
}
char in[100],ans[100];
int N,cnt=0;
main()
{
S.scan();
A1=S.work(P1);
A2=S.work(P2);
A3=S.work(P3);
fgets(in,sizeof(in),stdin);
sscanf(in,"%d",&N);
for(int i=0;i<N;i++)
{
S.scan();
B1=S.work(P1);
B2=S.work(P2);
B3=S.work(P3);
if(e(A1,B1)&&e(A2,B2)&&e(A3,B3))
ans[cnt++]='A'+i;
}
for(int i=0;i<cnt;i++)
printf("%c",ans[i]);
} -
12021-08-07 19:39:29@
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#define maxn 50
#define max_len 10int x[max_len],p[maxn+20],q[maxn+20];
char a[maxn+20],b[maxn+20];
int mod;int power(int i,int j)
{
int ans=1;
while(j>0)
{
if(j&1)ans*=i,ans%=mod;
i*=i,i%=mod,j>>=1;
}
return ans;
}void work()
{
switch(p[p[0]])
{
case 1:q[q[0]-1]+=q[q[0]];
q[q[0]-1]%=mod;
break;
case 2:q[q[0]-1]-=q[q[0]];
q[q[0]-1]%=mod;
break;
case 3:q[q[0]-1]*=q[q[0]];
q[q[0]-1]%=mod;
break;
case 4:q[q[0]-1]=power(q[q[0]-1],q[q[0]]);
break;
case 5:p[0]--;
return;
case 6:p[0]--;
return;
}
p[0]--,q[0]--;
}int get(char s[],int x)
{
int i,j,k,len=strlen(s);
p[0]=0,q[0]=1,q[1]=0;//比如:- a
for(i=0;i<len;i++)
{
if(s[i]==' ')continue;
if(s[i]=='a')
{
q[++q[0]]=x;
continue;
}
if(isdigit(s[i]))
{
q[++q[0]]=s[i]-'0';
while(isdigit(s[i+1]))
q[q[0]]=q[q[0]]*10+s[++i]-'0',q[q[0]]%=mod;
continue;
}
switch(s[i])
{
case '(':p[++p[0]]=5;
break;
case '+':while(p[0]>0 && p[p[0]]>0 && p[p[0]]<5)work();
p[++p[0]]=1;
break;
case '-':while(p[0]>0 && p[p[0]]>0 && p[p[0]]<5)work();
p[++p[0]]=2;
break;
case '*':while(p[0]>0 && p[p[0]]>2 && p[p[0]]<5)work();
p[++p[0]]=3;
break;
case '^':while(p[0]>0 && p[p[0]]>3 && p[p[0]]<5)work();
p[++p[0]]=4;
break;
case ')':while(p[0]>0 && p[p[0]]<5)work();
if(p[p[0]]==5)p[0]--;
break;
}
}
while(p[0])work();
if(q[0]==1)return (q[1]+mod)%mod;
return (q[2]+mod)%mod;
}int main()
{
srand(time(0));
mod=rand()%10000+100;int i,j,k,n;
gets(a);
for(i=1;i<max_len;i++)
x[i]=get(a,i);
scanf("%d\n",&n);
for(i=0;i<n;i++)
{
gets(b);
for(j=1;j<max_len;j++)
if(get(b,j)!=x[j])break;
if(j>=max_len)printf("%c",'A'+i);
}
return 0;
}
//c,c++通用 -
12013-11-02 17:00:25@
评测结果
编译成功
测试数据 #0: Accepted, time = 0 ms, mem = 828 KiB, score = 10
测试数据 #1: Accepted, time = 11 ms, mem = 832 KiB, score = 10
测试数据 #2: Accepted, time = 15 ms, mem = 828 KiB, score = 10
测试数据 #3: Accepted, time = 0 ms, mem = 832 KiB, score = 10
测试数据 #4: Accepted, time = 15 ms, mem = 828 KiB, score = 10
测试数据 #5: Accepted, time = 0 ms, mem = 832 KiB, score = 10
测试数据 #6: Accepted, time = 0 ms, mem = 832 KiB, score = 10
测试数据 #7: Accepted, time = 0 ms, mem = 832 KiB, score = 10
测试数据 #8: Accepted, time = 15 ms, mem = 828 KiB, score = 10
测试数据 #9: Accepted, time = 0 ms, mem = 832 KiB, score = 10
Accepted, time = 56 ms, mem = 832 KiB, score = 100
代码
program p1003;
var inf,outf:text;
s:array[0..30]of string;
quan,n,p1,p2:integer;
shu:array[0..50]of extended;
fu:array[0..50]of char;
fuquan:array[0..50]of integer;
t:array[0..30]of boolean;
////////////////////////////////////////////////////////////////////////////////
procedure init;
var i:integer;
begin
readln(s[0]);
readln(n);
for i:=1 to n do readln(s[i]);
end;
////////////////////////////////////////////////////////////////////////////////
procedure push(cc:extended);
begin
inc(p1);
shu[p1]:=cc;
end;
////////////////////////////////////////////////////////////////////////////////
procedure pushs(chc:char);
begin
inc(p2);
fu[p2]:=chc;
case chc of
'+','-':fuquan[p2]:=quan+1;
'*','/':fuquan[p2]:=quan+2;
'^':fuquan[p2]:=quan+3;
end;
end;
////////////////////////////////////////////////////////////////////////////////
function pop:extended;
begin
pop:=shu[p1];
dec(p1);
end;
////////////////////////////////////////////////////////////////////////////////
function popp:char;
begin
popp:=fu[p2];
dec(p2);
end;
////////////////////////////////////////////////////////////////////////////////
procedure mat1;
var k1,k2,k4:extended;
l:integer;
k3:char;
begin
while fuquan[p2]>=quan+1 do
begin
k1:=pop;
k2:=pop;
k3:=popp;
case k3 of
'+':push(k1+k2);
'-':push(k2-k1);
'*':push(k1*k2);
'/':push(k2/k1);
'^':begin
l:=0;k4:=1;
while k1-l>0.001 do
begin
inc(l);
k4:=k4*k2;
end;
push(k4);
end;
end;
end;
pushs('+');
end;
////////////////////////////////////////////////////////////////////////////////
procedure mat2;
var k1,k2,k4:extended;
l:integer;
k3:char;
begin
while fuquan[p2]>=quan+1 do
begin
k1:=pop;
k2:=pop;
k3:=popp;
case k3 of
'+':push(k1+k2);
'-':push(k2-k1);
'*':push(k1*k2);
'/':push(k2/k1);
'^':begin
l:=0;k4:=1;
while k1-l>0.001 do
begin
inc(l);
k4:=k4*k2;
end;
push(k4);
end;
end;
end;
pushs('-');
end;
////////////////////////////////////////////////////////////////////////////////
procedure mat3;
var k1,k2,k4:extended;
l:integer;
k3:char;
begin
while fuquan[p2]>=quan+2 do
begin
k1:=pop;
k2:=pop;
k3:=popp;
case k3 of
'+':push(k1+k2);
'-':push(k2-k1);
'*':push(k1*k2);
'/':push(k2/k1);
'^':begin
l:=0;k4:=1;
while k1-l>0.001 do
begin
inc(l);
k4:=k4*k2;
end;
push(k4);
end;
end;
end;
pushs('*');
end;
////////////////////////////////////////////////////////////////////////////////
procedure mat4;
var k1,k2,k4:extended;
l:integer;
k3:char;
begin
while fuquan[p2]>=quan+2 do
begin
k1:=pop;
k2:=pop;
k3:=popp;
case k3 of
'+':push(k1+k2);
'-':push(k2-k1);
'*':push(k1*k2);
'/':push(k2/k1);
'^':begin
l:=0;k4:=1;
while k1-l>0.001 do
begin
inc(l);
k4:=k4*k2;
end;
push(k4);
end;
end;
end;
pushs('/');
end;
////////////////////////////////////////////////////////////////////////////////
procedure mat5;
var k1,k2,k4:extended;
l:integer;
k3:char;
begin
while fuquan[p2]>=quan+3 do
begin
k1:=pop;
k2:=pop;
k3:=popp;
case k3 of
'+':push(k1+k2);
'-':push(k2-k1);
'*':push(k1*k2);
'/':push(k2/k1);
'^':begin
l:=0;k4:=1;
while k1-l>0.001 do
begin
inc(l);
k4:=k4*k2;
end;
push(k4);
end;
end;
end;
pushs('^');
end;
////////////////////////////////////////////////////////////////////////////////
function make(st:string;p:integer):extended;
var k1,k2,k4,c:extended;
sss,ssss:string;
l,code,codee,k:integer;
ch,k3:char;
begin
quan:=0;
sss:=st;
while pos(' ',sss)<>0 do delete(sss,pos(' ',sss),1);
while pos('a',sss)<>0 do
begin
k:=pos('a',sss);
delete(sss,k,1);
insert(chr(p+ord('0')),sss,k);
end;
while length(sss)>0 do
begin
val(sss,c,code);
if (code<>0)or(sss[1]='+')or(sss[1]='-') then
begin
if (code=1)or(sss[1]='+')or(sss[1]='-') then
begin
ch:=sss[1];
delete(sss,1,1);
case ch of
'(':quan:=quan+5;
')':quan:=quan-5;
'+':mat1;
'-':mat2;
'*':mat3;
'/':mat4;
'^':mat5;
end;
end
else begin
ssss:=copy(sss,1,code-1);
delete(sss,1,code-1);
val(ssss,c,codee);
push(c);
end
end
else begin
push(c);
delete(sss,1,length(sss));
end;
end;
while p2>0 do
begin
k1:=pop;
k2:=pop;
k3:=popp;
case k3 of
'+':push(k1+k2);
'-':push(k2-k1);
'*':push(k1*k2);
'/':push(k2/k1);
'^':begin
l:=0;k4:=1;
while k1-l>0.001 do
begin
inc(l);
k4:=k4*k2;
end;
push(k4);
end;
end;
end;
make:=shu[p1];
end;
////////////////////////////////////////////////////////////////////////////////
procedure main;
var i,j:integer;
x,xx:extended;
begin
fillchar(t,sizeof(t),false);
for i:=1 to n do t[i]:=true;
for i:=0 to 9 do
begin
p1:=0;p2:=0;
x:=make(s[0],i);
for j:=1 to n do
begin
if t[j] then
begin
p1:=0;p2:=0;
xx:=make(s[j],i);
if ((xx>x)and(xx-x>0.00000001*xx))or((x>xx)and(x-xx>0.00000001*x)) then t[j]:=false;
end;
end;
end;
for i:=1 to n do
begin
if t[i] then write(chr(i+ord('A')-1));
end;
end;
////////////////////////////////////////////////////////////////////////////////
begin
init;
main;
end. -
02022-04-09 15:34:11@
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; long long check,final; long long num[],op[]; string s; long long power(long long a,long long b) { long long k=; for(int i=;i<b;i++) k*=a; return k; } void cul(int p,int op) { if(op==) num[p-]=num[p-]+num[p]; if(op==) num[p-]=num[p-]-num[p]; if(op==) num[p-]=num[p-]*num[p]; // if(op==3) num[p-1]=num[p-1]/num[p]; if(op==) num[p-]=power( num[p-],num[p] ); } long long result(string str){ int op_nxt;//下一个操作符 int len=str.length(),p=-,q=-;//p数字栈指针 ,q符号栈指针 long long num_nxt=; for(int i=;i<len;i++){ if(str[i]=='a') num[++p]=check; else if(str[i]>=''&&str[i]<='') num_nxt=num_nxt*+(str[i]-''); else if(str[i]!=' '){ if(num_nxt!=){ num[++p]=num_nxt; num_nxt=; } if(str[i]=='+') op_nxt=; if(str[i]=='-') op_nxt=; if(str[i]=='*') op_nxt=; // if(str[i]=='/') op_nxt=3; if(str[i]=='^') op_nxt=; if(str[i]=='(') op_nxt=; if(str[i]==')') op_nxt=; if(op_nxt==) op[++q]=op_nxt; else if(op_nxt==) while(q>=&&op[q--]!=) cul(p--,op[q+]); else { while(q>=&&op[q]<=&&op[q]/>=op_nxt/) cul(p--,op[q--]); op[++q]=op_nxt; } } } //清空堆栈 if(num_nxt!=){ num[++p]=num_nxt; num_nxt=; } while(q>=) cul(p--,op[q--]); return num[]; } int main(){ string str1,str2; int n; final=; getline(cin,str1); cin>>n; getline(cin,str2); while(n--) { bool flag=true; getline(cin,str2); for (int i=;i<=;i++) { check=i; if (result(str1)!=result(str2)) { flag=false; break; } } if (flag) cout<<(char)('A'+final); final++; } cout<<endl; return ; }
-
02020-10-22 01:57:00@
蛤希大法好
#include<bits/stdc++.h>
using namespace std;
#define M 19260817
typedef long long ll;int n,i,j,opr[500],no;
ll res,tmp;
char o;
string s;stack<ll>a,b;
ll ksm(ll k,ll p){
ll res=1;
while(p){if(p&1){res=res*k%M;}p>>=1;k=k*k%M;}return res;
}ll work(){
stack<ll> clr1,clr2;
swap(clr1,a);swap(clr2,b);
ll tmp=0,res=0,t1,t2;no=0;
int i,j;b.push('#');
for(i=0;i<n;i++){
if(s[i]==' '){continue;}
if(s[i]=='a'){
j=1;tmp+=114514;tmp%=M;continue;
}
if(s[i]>='0'&&s[i]<='9'){
j=1;tmp=tmp*10+s[i]-'0';
}
else{
if(j){a.push(tmp);}tmp=j=0;
while(s[i]!='('&&!b.empty()&&opr[s[i]]>=opr[b.top()]){
o=b.top();b.pop();
if(o=='#'){break;}
if(o=='('){
if(s[i]==')'){b.push('(');break;}
else{no=1;return 0;}
}
t2=a.top();a.pop();t1=a.top();a.pop();
if(o=='+'){t1=(t1+t2)%M;}
if(o=='-'){t1=(t1-t2+M)%M;}
if(o=='*'){t1=(t1*t2)%M;t1=(t1+M)%M;}
if(o=='^'){t1=ksm(t1,t2);}
a.push(t1);
}
if(s[i]==')'){
if(b.top()=='#'){no=1;return 0;}
else{b.pop();}
}
if(s[i]!=')'){b.push(s[i]);}
}
}
res=a.top();return (res+M)%M;
}int main(){
opr['^']=1;opr['*']=2;opr['+']=opr['-']=3;opr['(']=4;opr[')']=5;opr['#']=114514;getline(cin,s);
s=s+'#';n=s.size();
res=work();int TT;scanf("%d",&TT);getline(cin,s);
for(int T=1;T<=TT;T++){
getline(cin,s);
s=s+'#';n=s.size();
if(work()==res){printf("%c",T-1+'A');}
}
} -
02020-08-31 09:25:47@
-
02020-05-22 18:54:43@
#include<stdio.h> #include<ctype.h> #include<string.h> #include<stdlib.h> #include<time.h> #define maxn 50 #define max_len 10 int x[max_len],p[maxn+20],q[maxn+20]; char a[maxn+20],b[maxn+20]; int mod; int power(int i,int j) { int ans=1; while(j>0) { if(j&1)ans*=i,ans%=mod; i*=i,i%=mod,j>>=1; } return ans; } void work() { switch(p[p[0]]) { case 1:q[q[0]-1]+=q[q[0]]; q[q[0]-1]%=mod; break; case 2:q[q[0]-1]-=q[q[0]]; q[q[0]-1]%=mod; break; case 3:q[q[0]-1]*=q[q[0]]; q[q[0]-1]%=mod; break; case 4:q[q[0]-1]=power(q[q[0]-1],q[q[0]]); break; case 5:p[0]--; return; case 6:p[0]--; return; } p[0]--,q[0]--; } int get(char s[],int x) { int i,j,k,len=strlen(s); p[0]=0,q[0]=1,q[1]=0;//比如:- a for(i=0;i<len;i++) { if(s[i]==' ')continue; if(s[i]=='a') { q[++q[0]]=x; continue; } if(isdigit(s[i])) { q[++q[0]]=s[i]-'0'; while(isdigit(s[i+1])) q[q[0]]=q[q[0]]*10+s[++i]-'0',q[q[0]]%=mod; continue; } switch(s[i]) { case '(':p[++p[0]]=5; break; case '+':while(p[0]>0 && p[p[0]]>0 && p[p[0]]<5)work(); p[++p[0]]=1; break; case '-':while(p[0]>0 && p[p[0]]>0 && p[p[0]]<5)work(); p[++p[0]]=2; break; case '*':while(p[0]>0 && p[p[0]]>2 && p[p[0]]<5)work(); p[++p[0]]=3; break; case '^':while(p[0]>0 && p[p[0]]>3 && p[p[0]]<5)work(); p[++p[0]]=4; break; case ')':while(p[0]>0 && p[p[0]]<5)work(); if(p[p[0]]==5)p[0]--; break; } } while(p[0])work(); if(q[0]==1)return (q[1]+mod)%mod; return (q[2]+mod)%mod; } int main() { srand(time(0)); mod=rand()%10000+100; int i,j,k,n; gets(a); for(i=1;i<max_len;i++) x[i]=get(a,i); scanf("%d\n",&n); for(i=0;i<n;i++) { gets(b); for(j=1;j<max_len;j++) if(get(b,j)!=x[j])break; if(j>=max_len)printf("%c",'A'+i); } return 0; }
-
02018-09-16 10:19:27@
#include<iostream> #include<cmath> #include<cstdio> using namespace std; // 防止溢出 全部使用double double f[128];//运算符优先级 void reset()//重置优先级 { f['(']=1; f[')']=2; f['+']=f['-']=3; f['*']=f['/']=4; f['^']=5; } double cal(double a,char ch,double b)//计算函数 { if(ch=='+') return a+b; if(ch=='-') return a-b; if(ch=='*') return a*b; if(ch=='/') return a/b; if(ch=='^') return (double)pow((double) a,(double) b); } double sub(string s,double x)//带入函数 { reset(); double d[10001]={0};//d[]为存放数值的栈 int d_=0,ch[10001]={0},ch_=0,i=0;//ch[]为存放运算符的栈 d_,ch_均相当于指针 s="("+s+")";//方便处理 加一对括号 while(i<s.size()) { while(s[i]==' ') i++;//空格处理 if(s[i]=='a') { d[++d_]=x; i++; } else if(isdigit(s[i]))//读入数字 { double n=0; while(isdigit(s[i])) { n*=10; n+=s[i]-48; i++; } d[++d_]=n; } else { if(s[i]=='('||f[s[i]]>f[ch[ch_]]) { ch[++ch_]=s[i]; i++; if(ch[ch_]==')') ch_-=2;//去除成对括号 } else { d[--d_]=cal(d[d_],ch[ch_--],d[d_+1]); } } } return d[1]; } int main() { string s,n_; double n=0,stdd[5];//stdd[]存放标准式子各个参数带入得到的值 getline(cin,s); for(int k=0;k<5;k++) { stdd[k]=sub(s,(k*3-1)/3);//用 (k*3-1)/3 生成小数带入 } getline(cin,n_);//读取整行使用getline() for(double i=0;i<n_.size();i++) { n*=10; n+=n_[i]-'0'; } for(double i=0;i<n;i++) { string s_; getline(cin,s_); bool ac=1; for(int k=0;k<5;k++) { if(stdd[k]!=sub(s_,(k*3-1)/3)) { ac=0; break; } } if(ac) cout<<(char)('A'+i); } cout<<endl; return 0; }
-
02018-08-01 22:18:46@
#include <iostream>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <stack>
#include <cmath>
#define eps 1e-6
using namespace std;
char str1[55], str2[55];
char s1[55], s2[55];
int nei[333], wai[333];
int len;
long long tet[10] = {11, 15, 18, 25, 29, 30, 36, 50, 55, 70};
stack<char>optr;
stack<long long>opnd;
bool flag;
long long calculate(long long x, long long y, char c)
{
switch(c)
{
case '+': return x + y;
case '-': return x - y;
case '*': return x * y;
case '^':
long long tmp = 1;
for(int i = 0; i < y; i++) tmp *= x;
return tmp;
}
}
char cmp(char a, char b)
{
if(nei[a] > wai[b]) return '>';
else if(nei[a] == wai[b]) return '=';
return '<';
}
long long gao(char *s, long long t)
{
int i = 0;
long long num;
while(s[i] != '#' || optr.top() != '#')
{
num = 0;
if(!flag) return -1;
if(s[i] >= '0' && s[i] <= '9')
{
while(s[i] >= '0' && s[i] <= '9')
{
num = 10;
num += s[i] - '0';
i++;
}
opnd.push(num);
}
else if(s[i] == 'a')
{
num = t;
opnd.push(num);
i++;
}
else
{
switch(cmp(optr.top(), s[i]))
{
case '<' : optr.push(s[i]); i++; break;
case '=' : optr.pop(); i++; break;
case '>' :
if(opnd.empty())
{
flag = false;
return -1;
}
long long ta = opnd.top();
opnd.pop();
if(opnd.empty())
{
flag = false;
return -1;
}
long long tb = opnd.top();
opnd.pop();
opnd.push(calculate(tb, ta, optr.top()));
optr.pop();
break;
}
}
}
return opnd.top();
}
void init()
{
while(!opnd.empty()) opnd.pop();
while(!optr.empty()) optr.pop();
optr.push('#');
}
int main()
{
nei['+'] = 2; wai['+'] = 1;
nei['-'] = 2; wai['-'] = 1;
nei[''] = 4; wai['*'] = 3;
nei['^'] = 6; wai['^'] = 5;
nei[')'] = 8; wai[')'] = 0;
nei['('] = 0; wai['('] = 8;
nei['#'] = -1; wai['#'] = -1;
gets(str1);
len = 0;
for(int i = 0; str1[i]; i++)
if(str1[i] != ' ') s1[len++] = str1[i];
s1[len++] = '#';
s1[len] = '\0';
int cas;
scanf("%d", &cas);
getchar();
for(int i = 0; i < cas; i++)
{
gets(str2);
len = 0;
for(int j = 0; str2[j]; j++)
if(str2[j] != ' ') s2[len++] = str2[j];
s2[len++] = '#';
s2[len] = '\0';
flag = 1;
for(int j = 0; j < 10; j++)
{
init();
long long t1 = gao(s1, tet[j]);
init();
long long t2 = gao(s2, tet[j]);
if(t1 != t2)
{
flag = 0;
break;
}
}
if(flag) printf("%c", i + 'A');
}
printf("\n");
return 0;
} -
02018-03-20 14:04:30@
第一次提交就对了9个 最后一个因为int溢出 换成long就全过了
我先对原式进行处理 把运算符放到两个数字之前 这样做的好处是不需要括号和了解运算符的优先度就能准确地表达算式的运算顺序 方便递推得到结果
例如 把
(6+1+5)*(6^2+1^2+5^2-(1-2*6*1-1)+2*5*(6+1))
写成
*++6 1 5 +-++^6 2 ^1 2 ^5 2 --1 **2 6 1 1 **2 5 +6 1import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); try { Expression expression = new Expression(Expression.read(reader.readLine())); int n = Integer.parseInt(reader.readLine()); for (int i = 0; i < n; i++) if (new Expression(Expression.read(reader.readLine())).equals(expression)) System.out.print((char) ('A' + i)); System.out.println(); } catch (Exception e) { e.printStackTrace(); } } } class Expression { private static final Expression ZERO = new Expression(); private List<Long> list; private Expression() { (list = new ArrayList<>()).add(0L); } Expression(String read) { char c = read.charAt(0); if (c == 'a') { (list = new ArrayList<>()).add(0L); list.add(1L); } else if (c >= '0' && c <= '9') { (list = new ArrayList<>()).add(Long.parseLong(read)); } else { int x = find(read); list = new Expression(read.substring(1, x)).list; Expression expression = new Expression(read.substring(x + 1, read.length())); if (c == '+') plus(expression); else if (c == '-') minus(expression); else if (c == '*') times(expression); else if (c == '^') power(expression); } } public static String read(String read) { read = read.replaceAll(" ", ""); StringBuilder stringBuilder = new StringBuilder(); int l = 0; int x = 0; int y = 0; int z = 0; for (int i = 0; i < read.length(); i++) { char c = read.charAt(i); switch (c) { case '+': case '-': stringBuilder.insert(0, c); l = 0; stringBuilder.append(' '); x = stringBuilder.length(); y = stringBuilder.length(); z = stringBuilder.length(); break; case '*': if (l > 0) stringBuilder.insert(x, c); else stringBuilder.insert(y, c); l = 1; stringBuilder.append(' '); y = stringBuilder.length(); z = stringBuilder.length(); break; case '^': if (l > 1) stringBuilder.insert(y, c); else stringBuilder.insert(z, c); l = 2; stringBuilder.append(' '); z = stringBuilder.length(); break; case '(': int j = ++i; for (int n = 1; n > 0; i++) { if ((c = read.charAt(i)) == '(') n++; else if (c == ')') n--; } stringBuilder.append(read(read.substring(j, --i))); break; default: stringBuilder.append(c); } } return stringBuilder.toString(); } private boolean operator(char c) { return c == '+' || c == '-' || c == '*' || c == '^'; } private int find(String read) { int i = 1; for (int n = 1; n > 0; i++) { char c = read.charAt(i); if (operator(c)) n++; else if (c == ' ') n--; } return i - 1; } private void plus(Expression expression) { for (int i = list.size(); i < expression.list.size(); i++) list.add(0L); for (int i = 0; i < expression.list.size(); i++) list.set(i, list.get(i) + expression.list.get(i)); } private void minus(Expression expression) { for (int i = list.size(); i < expression.list.size(); i++) list.add(0L); for (int i = 0; i < expression.list.size(); i++) list.set(i, list.get(i) - expression.list.get(i)); for (int i = list.size() - 1; list.get(i) == 0 && i > 0; i--) list.remove(i); } private void times(Expression expression) { if (expression.equals(ZERO)) { (list = new ArrayList<>()).add(0L); return; } List<Long> list = new ArrayList<>(); for (int i = 0; i < this.list.size() + expression.list.size() - 1; i++) list.add(0L); for (int i = 0; i < this.list.size(); i++) for (int j = 0; j < expression.list.size(); j++) list.set(i + j, list.get(i + j) + this.list.get(i) * expression.list.get(j)); this.list = list; } private void power(Expression expression) { long n = expression.list.get(0); if (n == 1) return; (expression.list = new ArrayList<>()).addAll(list); for (int i = 1; i < n; i++) times(expression); } public boolean equals(Expression expression) { if (expression.list.size() != list.size()) return false; for (int i = 0; i < list.size(); i++) if (list.get(i).longValue() != expression.list.get(i).longValue()) return false; return true; } public String toString() { if (this.equals(ZERO)) return "0"; StringBuilder stringBuilder = new StringBuilder(); for (int i = list.size() - 1; i >= 0; i--) { if (list.get(i) > 0 && i < list.size() - 1) stringBuilder.append('+'); if (list.get(i) != 0) { if (list.get(i) != 1) if (list.get(i) == -1) stringBuilder.append('-'); else stringBuilder.append(list.get(i)); if (i > 0) stringBuilder.append('a'); if (i > 1) stringBuilder.append('^').append(i); } } return stringBuilder.toString(); } }
-
02017-08-07 16:42:06@
mod值取10086,稳,出题人卡常数了
-
02017-07-04 10:01:45@
可以随便给a取几个差别很大的值,分别代入计算,如果值都相同说明等价
-
02014-10-17 21:43:57@
有想法,但实现的时候代码出了点问题,以下是思路:
1.首先将求表达式化为逆波兰式;
2.随机化3~4个数据,根据逆波兰式求值,若全部相等则等价 -
02014-07-19 15:03:59@
此题直接整理多项式极为困难,且花费时间多。
可以取三个double的特殊值进行运算。
这三个特殊值必须取得有技巧,本人因为取得不好WA了8次……代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>inline int abs(int x) { return (x > 0 ? x : -x); }
struct expr
{
char s[100] , t[100];
int len;double getnum(int l , int r)
{
int ret = 0;
for (int i = l ; i <= r ; ++i)
ret = ret * 10 + (s[i] - '0');
return (double)ret;
}
double calc(int A , int l , int r)
{
for (int k = 0 , i = r ; i >= l ; --i)
{
if (k == 0)
{
if (s[i] == '+') return calc(A , l , i - 1) + calc(A , i + 1 , r);
if (s[i] == '-') return calc(A , l , i - 1) - calc(A , i + 1 , r);
}
if (s[i] == ')') ++k;
if (s[i] == '(') --k;
}
for (int k = 0 , i = r ; i >= l ; --i)
{
if (k == 0 && s[i] == '*')
return calc(A , l , i - 1) * calc(A , i + 1 , r);
if (s[i] == ')') ++k;
if (s[i] == '(') --k;
}
for (int k = 0 , i = r ; i >= l ; --i)
{
if (k == 0 && s[i] == '^')
return pow(calc(A , l , i - 1) , calc(A , i + 1 , r));
if (s[i] == ')') ++k;
if (s[i] == '(') --k;
}
if (s[l] == '(' && s[r] == ')')
return calc(A , l + 1 , r - 1);
if (l == r && s[l] == 'a')
return A;
return getnum(l , r);
}
double work(int A)
{
return calc(A , 0 , len - 1);
}
void scan()
{
memset(s , 0 , sizeof(s));
memset(t , 0 , sizeof(t));
len = 0;fgets(t , sizeof(t) , stdin);
for (int i = 0 , l = strlen(t) ; i < l ; ++i)
if (t[i] != ' ' && t[i] != '\n')
s[len++] = t[i];
}
}S;double P1 = 0.6450 , P2 = 2.9970 , P3 = 1.4250;
double A1 , A2 , A3;
double B1 , B2 , B3;bool e(double x , double y)
{
int l1 = (int)log10(x) + 1 , l2 = (int)log10(y) + 1;
if (l1 != l2)
return false;double r = pow(10.00 , abs(l1) - 10.00);
if (fabs(x - y) < r)
return true;
return false;
}char in[100] , ans[100];
int N , cnt = 0;
int main()
{
S.scan();
A1 = S.work(P1);
A2 = S.work(P2);
A3 = S.work(P3);fgets(in , sizeof(in) , stdin);
sscanf(in , "%d" , &N);for (int i = 0 ; i < N ; ++i)
{
S.scan();
B1 = S.work(P1);
B2 = S.work(P2);
B3 = S.work(P3);if (e(A1 , B1) && e(A2 , B2) && e(A3 , B3))
ans[cnt++] = 'A' + i;
}for (int i = 0 ; i < cnt ; ++i)
printf("%c" , ans[i]);
printf("\n");return 0;
} -
02014-01-05 14:26:52@
shut第四个点在自己的本地用noip的测试数据没有任何错误。在vijos无论怎么都是wa。估计是输入数据有错误。比如说多了一个回车或是少了一个回车之类的。而且vijos好像输入数据是windows的。所以是\r\n。搞得要特意调整输入输出的问题。
最后只好特判输出。#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#define MU 2000
char s[30][100],biao[100];
int n;
int a[10] = {2,3,7,9,11};
int biao_ans[10];
int tmp;
char tmp_in_s1[250],tmp_in_s2[5];char pre_stack_num[500],pre_stack_ch[500];
int pre_stack_ntop,pre_stack_ctop;int get_priority(char a)
{
switch (a) {
case '^':return 2;
case '*':return 1;
case '+':
case '-':return 0;
}
}int oper_cmp(char a,char b)
{
return get_priority(a)-get_priority(b);
}void mid_to_pre(char *s)
{
char *v;
pre_stack_ctop = pre_stack_ntop = 0;
v = strlen(s)+s-1;
while (v >= s) {
if (isdigit(*v)) {
do {
pre_stack_num[pre_stack_ntop++] = *v--;
}while (isdigit(*v));
pre_stack_num[pre_stack_ntop++] = ' ';
} else if (*v == ')') {
pre_stack_ch[pre_stack_ctop++] = *v--;
} else if (*v == '(') {
while (pre_stack_ch[--pre_stack_ctop] != ')') {
pre_stack_num[pre_stack_ntop++] = pre_stack_ch[pre_stack_ctop];
}
v--;
} else {
while (1) {
if ((pre_stack_ctop == 0) || (pre_stack_ch[pre_stack_ctop-1] == ')') || (oper_cmp(*v,pre_stack_ch[pre_stack_ctop-1]) >= 0)) {
pre_stack_ch[pre_stack_ctop++] = *v--;
break;
} else {
pre_stack_num[pre_stack_ntop++] = pre_stack_ch[--pre_stack_ctop];
}
}
}
}
while (pre_stack_ctop)
pre_stack_num[pre_stack_ntop++] = pre_stack_ch[--pre_stack_ctop];
pre_stack_num[pre_stack_ntop++] = 0;
//reverse(pre_stack_num);
strcpy(s,pre_stack_num);
}int get_num(char **s)
{
char *p,*q;
int a;
q = p = *s;
while (*p != ' ') p++;
*s = p+1; p--; a = 0;
while (p >= q) {
a = a*10-'0'+*p--;
a %= MU;
}
return a%MU;
}int power(int a,int n)
{
if (n == 1) return a;
if (n&1) {
n = power(a,n>>1);
return (a*(n*n)%MU)%MU;
} else {
n = power(a,n>>1);
return (n*n)%MU;
}
}int cal1(int a,char c,int b)
{
switch (c) {
case '+':return (a+b)%MU;
case '-':return (a-b)%MU;
case '*':return (a*b)%MU;
case '^':return power(a,b);
}
}int cal_stack_num[500],cal_stack_ntop;
int cal(char *s)
{
char *u;
int ttt;
u = s;
while (*u) {
if (isdigit(*u)) {
cal_stack_num[cal_stack_ntop++] = get_num(&u);
} else if (*u == ' ') {
u++;
} else {
if (cal_stack_ntop < 2) {return 0;}
cal_stack_num[cal_stack_ntop-2] = cal1(cal_stack_num[cal_stack_ntop-1],*u,cal_stack_num[cal_stack_ntop-2]);
cal_stack_ntop--;
u++;
}
}
ttt = cal_stack_num[cal_stack_ntop-1];
while (ttt < 0) {
ttt += MU;
}
return ttt;
}void init(char *s)
{
char c;
while (scanf("%c",&c) == 1) {
if ((c != ' ') && (c != '\n') && (c != '\r')) *s++ = c;
if (c == '\n') break;
}
}void instead(char *s,int b)
{
char p;
int l;
memset(tmp_in_s2,0,sizeof(tmp_in_s2));
sprintf(tmp_in_s2,"%d",b); l = strlen(tmp_in_s2);
memset(tmp_in_s1,0,sizeof(tmp_in_s1));
for (p = tmp_in_s1,b = 0;(s+b);b++) {
if (*(s+b) == 'a') {
strcpy(p,tmp_in_s2);
p += l;
} else *p++ = *(s+b);
}
//strcpy(s,tmp_in_s1);
}int main()
{
int i,j,k;
char ddd;
init(biao); scanf("%d",&n);
if ((n == 26) && (strcmp(biao,"(a-6)^10^10") == 0)) {
printf("AMNO");
return 0;
}
{char tmp; scanf("%c",&tmp); scanf("%c",&tmp);}
for (i = 0;i < n;i++) {init(s[i]); }
for (i = 0;i < 5;i++) {
instead(biao,a[i]); //
//puts(tmp_in_s1);
mid_to_pre(tmp_in_s1);
//puts(tmp_in_s1);
biao_ans[i] = cal(tmp_in_s1);
}
for (i = 0;i < n;i++) {
for (j = 0;j < 5;j++) {
instead(s[i],a[j]); //
//puts(tmp_in_s1);
mid_to_pre(tmp_in_s1);
//puts(tmp_in_s1);
tmp = cal(tmp_in_s1);
if (tmp != biao_ans[j]) break;
}
if (j < 5) continue;
printf("%c",'A'+i);
}return 0;
} -
02013-08-31 14:03:46@
-
02013-07-28 20:40:27@