WHU寒假集训第一天----数论

A K尾相等数

 从键盘输入一个自然数K(K>1),若存在自然数M 和N(M>N),使得K^M 和K^N 均大
于或等于1000、且它们的末尾三位数相等,则称M 和N 是一对“K 尾相等数”。请编写程
序,输出M+N 值最小的K 尾相等数。

 
一个数的N次幂的末三位,就是000~999这1000种情况,并且当我们算该数的N=1,2,3…次幂时发现,当大于1000时的末三位数出现第二次时,即发现M+N值最小的K尾相等数

代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define LEN 1000

int  main(){
    int k,i,tail[LEN],m,flag;
    while(scanf("%d",&k)!=EOF)
 {
    if(k==0) break;
    flag=0;   
    i=m=1;
    memset(tail,0,sizeof(tail));
 
    if(k>=LEN)
 {
        k=k%LEN;
        flag=1;
    }
 while(1){
        i*=k;
        if(i>=LEN || flag==1)
  {
            if(tail[i%LEN]==0) tail[i%LEN]=m;
            else {tail[i%LEN]+=m;break;}  
            flag=1;
        }
        if(i>=LEN) i=i%LEN;
        m++;
    }
    printf("%d\n",tail[i%LEN]);
    }
}

B 3n+1 数链问题

直接模拟 RMQ一直没有实现

代码

#include <iostream>
#include <stdlib.h>
using namespace std;
int done(int i, int j)
{
      int max=0,count,n;
      for(int m=i; m<=j; m++){
          count=1;
          n=m;
          while(n!=1){
              if(n%2==0)
      n=n/2;
              else
      n=n*3+1;;
              count++;
          }
          if(count>max) max=count;
      }
      return max;
}
int main()
{
      int i,j,sum;
      while(cin>>i>>j){
       if(i==0&&j==0) break;
          if(i>j) sum=done(j,i);
          else sum=done(i,j);
      cout<<sum<<endl;
 }
    return 0;
}

C计算a^b mod c
代码
int modular(int a,int b,int m)
{
    int t=a,tt=1;
    while(b)
    {
        if(b%2)tt=(tt*t)%m;
        t=(t*t)%m;
        b/=2;
    }
    return tt;
}

D 负权数

算法思想:

n>0r>0

n=an*r^n+an-1*r^(n-1)+…+a0*r^0;

现在讨论r<0的情况

 

如果n>0

n=an*|r|^n+an-1*|r|^(n-1)+…+a0*|r|^0;

设其中某项为ap*|r|^pp!=0

p为偶数的时候ap*r^p不变

p为奇数的时候则变为相反数

构造

ap*|r|^p=r^(p+1)+(|r|- ap)*r^p;

 

如果n<0

p为奇数的时候不变

p为偶数的变为相反数

 

算法步骤:

nr取绝对值

|n|表示为|r|进制然后根据n的正负针对构造进行相应的操作

既将本位换为|r|-ap并且对高位加一

 

代码相关问题:

子函数tentor:将十进制n转换为r进制

子函数increase: 实现高位进位的操作可能改变数字的位数

子函数output:高于十进制的表示方法

注意对0的处理


代码
#include <stdio.h>
#include <string.h>
#include <math.h>
int n,r,nn,rr,num[101],p,len;
void tentor()
{
 int a,b;
 a=nn,b=rr,len=0;
 memset(num,0,sizeof(num));
 while(a)
 {
  num[len++]=a%b;
  a/=b;
    }
}
void increase(int p)
{
  while(++num[p]>=rr)
  { 
       num[p]=rr-num[p];
       p++;
     }
    if(p>=len) len++;
}
void output()
{
 int i;
 for(i=len-1;i>=0;i--)
 {
  if(num[i]<10) printf("%d",num[i]);
  else  printf("%c",55+num[i]);
    }
    printf("\n");
}
int main()
{
 while(scanf("%d%d",&n,&r)!=EOF)
 {
  if(n==0&&r==0)  break;
  if(n==0) printf("0\n");
  else
  {
  nn=fabs(n);
  rr=fabs(r);
  tentor();
  p=n>0?1:0;
  for(;p<len;p+=2)
  {
     if(num[p]!=0)
     {
    num[p]=rr-num[p];
    increase(p+1);
     }
  }
  output();
    }
    }
}
G:数值转换

我是直接观察的出的结论
代码
#include<stdio.h>
#include<string.h>
char num[1002];
int len;
int main()
{
 int n,t;
 scanf("%d",&t);
 while(t--)
 {
  scanf("%d",&n);
  len=0;
  if(n==0)
  printf("0\n");
  else
  {
  while(n!=0){
   if(n>0)
    switch(n%3){
     case 0: num[len++]='0'; n/=3; break;
     case 1: num[len++]='1'; n=(n-1)/3; break;
     case 2: num[len++]='-'; n=(n+1)/3; break;
    }
   else
    switch(-n%3){
     case 0: num[len++]='0'; n/=3; break;
     case 1: num[len++]='-'; n=(n+1)/3; break;
     case 2: num[len++]='1'; n=(n-1)/3; break;
   }
  }
  while(--len>=0) putchar(num[len]);
  puts("\0");
  }
 }
}

还有质多项式 猴子舞 大众匹萨没有作出来 做出来再贴

posted on 2008-01-21 10:34 Victordu 阅读(1668) 评论(8)  编辑 收藏 引用

评论

# re: WHU寒假集训第一天----数论 2008-01-21 15:24 Louix

A题既然使用数论为什么不用更好的结论呢,求K^X mod 1000的循环周期可以把1000素因子分解,求K^X2 mod 2,K^X5 mod 5的循环周期然后可以很快计算出mod 1000的循环周期。
如果不苛求时间,你的解法还有不需要数组的实现。  回复  更多评论   

# re: WHU寒假集训第一天----数论 2008-01-21 19:49 Victordu

谢谢!这也正是我疑惑的一个地方 我只是进行了猜想但没有证明 具体应该怎么求出循环周期呢 望指教!水平有限 请包涵!@Louix
  回复  更多评论   

# re: WHU寒假集训第一天----数论 2008-01-23 01:40 Louix

简单说下,设pa、pb互素,A小于pa、pb且与pa、pb互素,A^(Ka + Ca) mod pa = A^Ca mod pa,A^(Kb + Cb) mod pb = A^Cb mod pb,那么A^(lcm(Ka, Kb) + lcm(Ca, Cb)) mod pa * pb = A^lcm(Ca, Cb),lcm代表最小公倍数。
这是我推导的结论,你也验证下看正确么。  回复  更多评论   

# re: WHU寒假集训第一天----数论 2008-01-23 01:41 Louix

上面的错误,A不需要与pa、pb互素。  回复  更多评论   

# re: WHU寒假集训第一天----数论 2008-01-23 13:20 R2@whuacm

今天在cppblog首页突然发现有人写WHU寒假集训,好亲切,看ID,原来是熟人,呵呵  回复  更多评论   

# re: WHU寒假集训第一天----数论[未登录] 2008-01-24 18:46 tim

纯支持  回复  更多评论   

# re: WHU寒假集训第一天----数论 2008-01-26 13:50 amazingjxq

有没有哪个oj上有这道题?测试一下  回复  更多评论   

# re: WHU寒假集训第一天----数论[未登录] 2008-01-29 17:54 victordu

恩 WOJ 武大的 最后一版@amazingjxq
  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2008年2月>
272829303112
3456789
10111213141516
17181920212223
2425262728291
2345678

统计

常用链接

留言簿(5)

随笔档案(46)

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜