您的位置:首页 > 其它

UVALive 4119 Always an integer(差分数列+模拟)

2015-10-02 22:13 441 查看

UVALive - 4119 Always an integer

题意:

输入一个关于n的表达式,求该表达式对于任意整数变量n得到的值是否均为整数。

思路:

根据差分数列的性质,令 n = 1 , 2 ,3 ,…,k+1,依次带入表达式计算是不是整数。其中k为表达式的最高次幂,

写这个题主要还是锻炼一下自己写模拟题的能力。。

代码:

/*
* @author FreeWifi_novicer
* language : C++/C
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>

using namespace std;

#define clr( x , y ) memset(x,y,sizeof(x))
#define cls( x ) memset(x,0,sizeof(x))
#define pr( x ) cout << #x << " = " << x << endl
#define pri( x ) cout << #x << " = " << x << " "
#define test( t ) int t ; cin >> t ; int kase = 1 ; while( t-- )
#define out( kase ) printf( "Case %d: " , kase++ )
#define mp make_pair
#define pii pair<int,int>
#define pb push_back
typedef long long lint;
typedef long long ll;
typedef long long LL;

string s ;
vector<pair<lint , int> >v ;
int maxe ;
lint d ;
void init(){
int k = 0 ;
v.clear() ;
while( s[k] != '/' ) k++ ;
d = abs( atol( s.c_str() + k + 1 ) );
s = s.substr( 0 , k ) ;
int len = s.length() ;
int begin = ( s[0] == '-' )? 2 : 1 ;
if( isdigit( s[begin] ) || s[begin] == 'n' ){
begin -- ;
s[begin] = '+' ;
}
len-- ;
maxe = 0 ;
for( int i = begin ; i < len ; i++ ){
if( s[i] == '+' || s[i] == '-' ){
i++ ;
lint c ; int e ;
if( s[i] == 'n' ){
c = ( s[i-1] == '-' )? -1 : 1 ;
if( s[i+1] == '^' ){ //n^e
e = atoi( s.c_str() + i + 2 ) ;
while( i + 2 < len && isdigit( s[i+2] ) ) i++ ;
i++ ;
}
else if( s[i+1] != '^' ){//n
e = 1 ;
}
}
else if( isdigit( s[i] ) ){
c = atol( s.c_str() + i ) ;
if( s[i-1] == '-' )
c = -c ;
while( i + 1 < len && isdigit( s[i+1] ) ) i++ ;
if( s[i+1] == 'n' && s[i+2] == '^' ) {//cn^e
i ++ ;
e = atoi( s.c_str() + i + 2 ) ;
while( i + 2 < len && isdigit( s[i+2] ) ) i++ ;
i++ ;
}
else if( s[i+1] == 'n' && s[i+2] != '^' ){//cn
i ++ ;
e = 1 ;
}
else if( s[i+1] != 'n' ){//c
e = 0 ;
}
}
maxe = max( maxe , e ) ;
v.pb( mp( c , e ) ) ;
}
}
}
lint fast_pow( lint x , int n ){
lint res = 1 ;
while( n ){
if( n & 1 )
res = res * x % d ;
n >>= 1 ;
x = x * x % d ;
}
return res ;
}
lint calc( int n ){
lint sum = 0 ;
for( int i = 0 ; i < int( v.size() ) ; i++ ){
lint c = v[i].first ;
int e = v[i].second ;
if( c )
sum = ( sum + c * fast_pow( n , e ) % d ) % d ;
sum = ( sum + d ) % d ;
}
return sum  ;
}
void work(){
init() ;
bool ok = true ;
for( int i = 1 ; i <= maxe + 5 ; i++ ){
lint x = calc( i ) ;
if( x ){
ok = false ;
break ;
}
}
if( ok )
puts( "Always an integer" ) ;
else
puts( "Not always an integer" ) ;
s.clear() ; v.clear() ;
}
int main(){
int kase = 1 ;
while( cin >> s && s != "." ){
out(kase) ;
work() ;
}
return 0;
}


补一个求表达式值的模板:

map<char,int>priv ;
map<char,double>value ;

double calc( double a , double b , char op ){
if( op == '+' ) return a + b ;
if( op == '-' ) return a - b ;
if( op == '*' ) return a * b ;
if( op == '/' ) return a / b ;
if( op == '^' ) return exp( log(a) * b ) ;
//if( op == '^' ) return fast_pow( a , b ) ;
}
/*中缀表达式计算,str = "x^2+(12n+11/3+x)-5^n" , val['x']=1 , val['n']=2*/
double calculate( string str , map<char,double> val ){
stack<double>num ;
stack<char>oper ;
priv['+'] = priv['-'] = 3 ;
priv['*'] = priv['/'] = 2 ;
priv['^'] = 1 ;
priv['('] = 10 ;

double x , y ;
char last = 0 ;
int len = str.length() ;
for( int i = 0 ; i < len ; i++ ){
if( isalpha( str[i] ) )
num.push( val[str[i]] ) ;
else if( isdigit( str[i] ) ){
num.push( atof( str.c_str() + i ) ) ;
while( i + 1 < len && isdigit( str[i+1] ) ) i++ ;
if( i + 1 < len && str[i+1] == '.' ){
i++ ;
while( i + 1 < len && isdigit( str[i+1] ) ) i++ ;
}
if( i + 1 < len && isalpha( str[i+1] ) )
oper.push( '*' ) ;
}
else if( str[i] == '(' )
oper.push( str[i] ) ;
else if( str[i] == ')' ){
while( oper.top() != '(' ){
y = num.top() ; num.pop() ;
x = num.top() ; num.pop() ;
char op = oper.top() ;
oper.pop() ;
num.push( calc( x , y , op ) ) ;
}
oper.pop() ;
}
else if( str[i] == '-' && ( last == 0 || last == '(' ) ){
num.push( 0.0 ) ;
oper.push( '-' ) ;
}
else if( priv[str[i]] > 0 ){
while( !oper.empty() && priv[str[i]] >= priv[oper.top()] ){
y = num.top() ; num.pop() ;
x = num.top() ; num.pop() ;
char op = oper.top() ;
oper.pop() ;
num.push( calc( x , y , op ) ) ;
}
oper.push( str[i] ) ;
}
else continue ;
last = str[i] ;
}
while( !oper.empty() ){
y = num.top() ; num.pop() ;
x = num.top() ; num.pop() ;
char op = oper.top() ;
oper.pop() ;
num.push( calc( x , y , op ) ) ;
}
return num.top() ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数论