UVALive 4119 Always an integer(差分數列+模擬)

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() ;
}

發佈了127 篇原創文章 · 獲贊 14 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章