• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

会点儿code

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

2008 world final B (Always an Integer)

// 265405   2008-04-18 09:37:54  Accepted 0.205 404 13603 C++ 4119 - Always an integer 

/*

问题是判断一个整系数多项式能否总是被整数 divisor 整除
如果 divisor 比较小,我们考虑该整系数多项式 Q(n),看Q(0),Q(1),...,Q(divisor-1)能否被 divisor 整除
每次判断整除性相当于计算多项式值(附带对divisor取模),根据秦九韶算法,复杂度为 O(deg Q),deg Q 为多项式 Q 的次数,故总的复杂度为 O( degQ * divisor )

设给定的多项式为Q(n),如果对于所有的n>0都有 D|Q(n)
显然要满足D|Q(1), 而且Q(n)的差分多项式Q(n+1)-Q(n)也要能被D整除

刚才的思路是计算出 Q'(n) = Q(n+1)-Q(n)
然后在判断 Q'(n)是否满足对与所有n>0 有D|Q'(n)
其实可以不算Q'(n) 直接算是否 D|(Q(n+1)-Q(n))

第一次看是否D整除 Q(1)
第二次看是否D整除 Q(2)-Q(1)    相当与Q'(1)
第三次看是否D整除 Q(3)-2Q(2)+Q(1)   相当与Q''(1)

这时候会发现, 只要计算 Q(1),Q(2),...,Q(degree), 并且判断是否每个值都能被D整除就可以了
因为
第一次查看 Q(1)是否被D整除,如果可以那么
第二次查看 Q(2)-Q(1)是否被D整除,根据上一步的结果,只要满足 Q(2)被D整除就可以有Q(2)-Q(1)被D整除
第三次。。。类似 只要判断是否 Q(3)被D整除
第N次

这些过程中只要出现一次 不能被D整除的 可以马上得出  Not always an integer

*/


#include <stdio.h>
#include <string.h>

// --------------------------------------------------------------------- //
// 类型: Polynomial
// 整系数多项式,附带一个整数的除数
// --------------------------------------------------------------------- //

// 整系数多项式的最高次数
#define Emax 100

bool IsDigit(char c) {
     return c>='0' && c<='9';
}
inline int mmax(int a, int b) {
     return a>b?a:b;
}
inline int mmin(int a, int b) {
     return a<b?a:b;
}

// 类定义: Polynomial
class Polynomial{
public:
//-------------- 公共成员变量 ---------------//

     int m_degree;            // 整系数多项式的次数
     int m_divisor;     // 整系数多项式的除数
     int m_tab[101];           // 整系数多项式的“系数-幂”对应表

//-------------- 公共成员函数 --------------//

     // 初始化为一个零多项式
     Polynomial(void){
          m_degree = 0;
          memset(m_tab, 0, sizeof(m_tab));
     }

     // 计算系数
     int GetCoef(char* str, int index) {
          // 省去若干
     }

     // 计算指数
     int GetExp(char* str, int index) {
          // 省去若干
     }

     // 创建一个多项式
     void create_polynomial(char* str){
          // 省去若干
     }

     // 判断是否恒被 m_divisor 整除
     bool always_divisibility(void){
          int i;
          for(i=0; i<=m_degree; i++) {
               if( evaluate(i) != 0 ) {
                    return false;
               }
          }
          return true;
     }

//-------------- 私有成员函数 ---------------//

     // 计算多项式的值(对 m_divisor 求余, 注意可能发生的数据溢出问题)
     int evaluate(int n){
          long long val = 0;
          for(int pow = m_degree; pow >= 0; pow--) {
               val = ((val*n)%m_divisor + m_tab[pow])%m_divisor;
          }
          return (int)val;
     }

};

// --------------------- 主函数 ------------------------- //
int main()
{
     char str[10000];
     char c;
     int i;

     for(int cases=1; true; cases++){
          // input        
          i = 0;
          do{
               while( (c=getchar()) != '\n' ) {
                    if( c==' ' )          continue;
                    str[i++] = c;
               }
               str[i] = 0;
          }while( strlen(str) == 0 );

          if( str[0] == '.' )
               break;

          // create a polynomial
          Polynomial poly;
          poly.create_polynomial(str);

          // judge and output
          printf("Case %d: ", cases);
          if( poly.always_divisibility() )
               printf("Always an integer\n");
          else
               printf("Not always an integer\n");
     }

     return 0;
}

/*
在和钝剑经过激烈的讨论后终于得出了满意的算法,很高兴,希望大家能多多讨论。
在这里感谢钝剑大牛提供我初步代码。
另外这题的字符串解析也是很令人头痛的一步, 在这步因为不够细心WA了N次, 比赛的时候要是遇到这种东西就郁闷了.....
*/

posted on 2008-04-21 18:57  曹某  阅读(377)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3