33,009
社区成员
发帖
与我相关
我的任务
分享
class WaterNum:
"""Search Water Num
.....................
"""
def __init__(self,N = 21):
self.N = N
self.sum = 0 # sum
self.k_sum = 0
self.pow21 = [pow(i * -1,self.N) for i in range(-9,1)]
self.length = [len(str(i)) for i in self.pow21]
self.count = [-1 for i in range(10)] # initialize zero
self.max_num = pow(10,N)
self.min_num = pow(10,N - 2)
print('pow21:',self.pow21)
print('length:',self.length)
def increase_sum(self,freq = 0):
""" add the new vlaue
"""
if freq != 0:
self.sum += self.pow21[self.k] * freq
self.k_sum += freq
elif self.count[self.k] != 0:
self.sum += self.pow21[self.k]
self.k_sum += 1
def decrease_sum(self):
""" minus the mistake value
"""
k = self.k
self.sum -= self.pow21[k] * self.count[k]
self.k_sum -= self.count[k]
def set_filter(self):
""" calculate the frequency of every digits
"""
#print(self.k)
#for index in range(self.k + 1,10):
#self.count[index] = 0
self.filter = [0 for i in range(10)]
sum_str = str(self.sum)
#print(sum_str)
s_temp = sum_str[:-self.length[self.k]]
for ch in s_temp:
self.filter[9 - int(ch)] += 1
#print(s_temp)
#print(self.filter)
def check(self):
""" check the frequency of the digits in the front is ok
"""
for index in range(self.k):
if self.count[index] < self.filter[index]:
#print('return False index:',index)
return False
if self.sum > self.max_num:
return False
#print('return True')
return True
def right_print(self):
""" if this is a right answer,print it
"""
s_str = str(self.sum)
count_temp = [0 for i in range(10)]
for ch in s_str:
count_temp[9 - int(ch)] += 1
for i in range(10):
if self.count[i] != count_temp[i]:
return False
print('found',s_str)
return True
def search(self):
""" begin search
.......................
"""
self.k = 0
self.count[self.k] += 1
while self.k >= 0:
self.count[self.k] += 1
self.increase_sum()
self.set_filter()
#print('count:',self.count,'sum:',self.sum,'k_sum',self.k_sum,'filter:',self.filter)
if self.check() == False:
#print('at 1')
self.decrease_sum()
self.k -= 1
elif self.k >= 9 or self.k_sum >= self.N:
#print('at 2')
self.right_print()
self.decrease_sum()
self.k -= 1
# this number is in the range,we judge it
else:
#print('at 3')
self.k += 1
f_num = self.filter[self.k] - 1
self.count[self.k] = f_num
if f_num > -1:
self.increase_sum(f_num)
# self.count[k] = -1
import time
if __name__ == '__main__':
water_num = WaterNum(39)
water_num.search()
//不依赖大数 速度较快
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstring>
/**************************水仙花数**************************/
#define N 10
using namespace std;
void Narcissus(const int& n); //输出n位数中的水仙花数
int main(void)
{
clock_t start , end;
int n=1;
start=clock();
while(1)
{
std::cout<<"水仙花数位数:";
cin>>n;
start=clock();
Narcissus(n);
end=clock();
std::cout<<"Times:"<<(double)(end-start)/CLK_TCK<<std::endl;
}
//end=clock();
//std::cout<<"Times:"<<(double)(end-start)/CLK_TCK<<std::endl;
return 0;
}
static void StatNumber(int *num,int (&s)[N],const int& n)
{//统计num[]中 各数字出现的次数 结果放到S[]中
memset(s,0x00,sizeof(int)*N);
register int len=n;
const int* ptr=num;
while(len--)
{
++s[*ptr++];
}
}
static void Power_N(int *sum,const int& pow)
{ //对0~9的M次预处理将结果放入sum中,各数位拆解
register int i;
for(i = 1 ; i < N; i++) //初始化sum
{
sum[i*pow]=i;
}
for( i = 0 ;i < N; i++) //对0~9的M次预处理
{
int tmp;
for( int j = 0 ; (j < pow -1);j ++)
{
tmp=i*pow;
for( int n = 0 ; n < pow; n ++)
sum[tmp+n]*=i;
for(int m = 0 ; m < pow ; m ++)
{
if(sum[tmp+m]>=10)
{
if(sum[tmp+m+1] == -1)
sum[tmp+m+1] = 0;
sum[tmp+m+1] += sum[tmp+m]/10;
sum[tmp+m] = sum[tmp+m]%10;
}
}
}
}
}
static void Print(int *sum,const int& n)//输出水仙花数
{
register int i = n-1;
for(; i >= 0 ; i --)
{
std::cout<<sum[i];
}
std::cout<<std::endl;
}
static void add(int *addend,int *summend,const int& k,const int& pow )
{ //加入k的pow次方
register int i;
const int j=k*pow;
for( i = 0 ; i < pow; i ++)
addend[i] += summend[j+i];
for( i = 0 ; i < pow ; i ++)
{
if(addend[i]>=10)
{
if(addend[i+1] == -1)
addend[i+1] = 0;
addend[i+1] += addend[i]/10;
addend[i] = addend[i]%10;
}
}
}
static void sub(int *a,int *b,const int& k,const int& pow )//从a中减去k的pow次方
{
const int j=k*pow;
for(register int i = 0 ; i < pow; i++)
{
if(a[i] < b[j+i])
{
a[i+1] -= 1;
a[i]=a[i]+10-b[j+i];
}
else
{
a[i] -= b[j+i];
}
}
}
static bool cmp(int (&a)[N],int (&b)[N])//比较
{
for(register int i = 0 ; i < N; i++)
if(a[i]!=b[i])
return false;
return true;
}
void Narcissus(const int& n)
{
if(n <= 0) return;
int *sum=new int[n*N]; //0~9的n次方
memset(sum,0,sizeof(int)*n*N);
int stat1[N]={0}; //N次方和中各位数字出现的次数
int stat2[N]={0}; //栈中数出现的次数
int *gross=new int[n+1]; //栈中各数的n次方和 数字已拆分
memset(gross,0x00,sizeof(int)*(n+1));
int *stack=new int[n+1]; //栈
memset(stack,0x00,sizeof(int)*(n+1));
int* top=stack; //栈顶指针
const int *maxTop=stack+n; //
Power_N(sum,n); //求出0~9的n次方
bool tab = false;
register int k =9; //动态组合的数字 从大到小组合
while(1)
{
if(top < maxTop && gross[n]==0)
{ //栈中数字及N次方和均未达到N位
add(gross,sum,k,n);
stat2[k]++; //记录栈中各数字出现次数
*top++ = k; //数字入栈 栈顶不会大于后面的数字777-776.即780不会有
} //因无++K,只有--K.已出现过的组合后面不会再现 如731已现,无371/137/713/173
if(gross[n]>0) //组合数字的N次方和大于N位
{
sub(gross,sum,k,n);
stat2[k]--;
k=*--top - 1; //退栈,组合数字为退出数减一,后面不会有比前面更大的组合数字
}
if(top == maxTop) //栈满 即已有N位数字
{
if(gross[n-1]==0) //N次方和小于N位 若n为1,不能输出0,此处退出
break; //由于后面无比它更大的组合(见165-172行注释),退出
StatNumber(gross,stat1,n);//求N次方和中各位数出现次数 存于sta1中
if(cmp(stat1,stat2)) //若出现的数字及其次数完全相同,则为水仙花数
{
Print(gross,n); //若栈中为7 3 1则输出371
}
if(*(top-1) != 0) //若栈顶数字不为0
{
sub(gross,sum,k,n); //先从N次方和中减去此数字的N次方
--stat2[k]; //此数次数随即减少 此时栈顶指针未动
}
else
{
while(*(top-1) == 0) //栈顶为0 循环后指向栈中紧跟的非0数字
{
--top;
--stat2[0]; //退0
}
//if(top-1<stack) break;
tab=true;
}
k=*--top; //退栈 k接收退出的数字
if(tab)
{
sub(gross,sum,k,n); //
--stat2[k];
tab = false;
}
--k; //后面的组合数字比原数更小 保证不出现 788
}
//if(*stack ==1) break;
}
delete []sum;
delete []gross;
delete []stack;
}
import java.math.BigInteger;
import java.util.Arrays;
public class da2 {
static BigInteger[] table = new BigInteger[10];
static BigInteger sum = BigInteger.ZERO;
static int times = 0;
static BigInteger MAX = BigInteger.TEN.pow(21).subtract(BigInteger.ONE);
static BigInteger MIN = BigInteger.TEN.pow(21 - 1);
public static void main(String[] args) {
long time = System.nanoTime();
int n = 21;
int[] nums = new int[n];
//for(int i = 0;i < nums.length;i++)
//{
// nums[i] = 1; ------------把这删掉
//}
for (int i = 0; i < 10; i++)
table[i] = BigInteger.valueOf(i).pow(n);
f(0,n,nums,0);
time = System.nanoTime() - time;
System.out.println(time / 1000000000.0 + "s");
System.out.println("循环次数:"+times);
}
public static void f(int i,int n,int[] nums,int m)
{
if(i > n - 1)
{
times++;
if(panduan(nums))
System.out.println(sum);
}
else
{
for(int v = m;v < 10;v++)
{
nums[i] = v;
sum = sum.add(table[v]);
f(i+1,n,nums,v);
sum = sum.subtract(table[v]);
}
}
}
public static boolean panduan(int[] nums)
{
if(sum.compareTo(MAX)>0||sum.compareTo(MIN)<0)
return false;
String s = String.valueOf(sum);
int length = s.length();
int[] a = new int[length];
for (int i = 0; i < length; i++)
a[i] = s.charAt(i) - '0';
int[] b = nums.clone();
Arrays.sort(a);
Arrays.sort(b);
return Arrays.equals(a, b);
}
}
import java.math.BigInteger;
import java.util.Arrays;
public class da2 {
static BigInteger[] table = new BigInteger[10];
static BigInteger sum = BigInteger.ZERO;
static int times = 0;
static BigInteger MAX = BigInteger.TEN.pow(21).subtract(BigInteger.ONE);
static BigInteger MIN = BigInteger.TEN.pow(21 - 1);
public static void main(String[] args) {
long time = System.nanoTime();
int n = 21;
int[] nums = new int[n];
for(int i = 0;i < nums.length;i++)
{
nums[i] = 1;
}
for (int i = 0; i < 10; i++)
table[i] = BigInteger.valueOf(i).pow(n);
f(0,n,nums,0);
time = System.nanoTime() - time;
System.out.println(time / 1000000000.0 + "s");
System.out.println("循环次数:"+times);
}
public static void f(int i,int n,int[] nums,int m)
{
if(i > n - 1)
{
times++;
if(panduan(nums))
System.out.println(sum);
}
else
{
for(int v = m;v < 10;v++)
{
nums[i] = v;
sum = sum.add(table[v]);
f(i+1,n,nums,v);
sum = sum.subtract(table[v]);
}
}
}
public static boolean panduan(int[] nums)
{
if(sum.compareTo(MAX)>0||sum.compareTo(MIN)<0)
return false;
String s = String.valueOf(sum);
int length = s.length();
int[] a = new int[length];
for (int i = 0; i < length; i++)
a[i] = s.charAt(i) - '0';
int[] b = nums.clone();
Arrays.sort(a);
Arrays.sort(b);
return Arrays.equals(a, b);
}
}
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>
#include <sys/time.h>
#define N 21
#define NUMBER_LENGTH_MAX 30
struct number
{
char digits[NUMBER_LENGTH_MAX];
int length;
};
struct counter
{
int digits[10];
int offset;
};
void assign(struct number *a, int b)
{
a->length = 0;
memset(&a->digits[0], 0, NUMBER_LENGTH_MAX);
if (b == 0) a->length = 1;
while(b > 0)
{
a->digits[a->length++] = b % 10;
b /= 10;
}
}
void copy(struct number *src, struct number *dst)
{
dst->length = src->length;
memcpy(&dst->digits[0], &src->digits[0], NUMBER_LENGTH_MAX);
}
void print(struct number *a)
{
char *p = &(a->digits[0]);
char *endp = &(a->digits[0]) + a->length;
do
{
endp--;
printf("%c", "0123456789"[(int)*endp]);
}while(endp != p);
}
void add(struct number *a, struct number *b)
{
int len = (a->length > b->length) ? a->length : b->length;
int i;
int carry = 0;
int d;
for (i = 0; i < len; i++)
{
d = (a->digits[i] + b->digits[i] + carry);
a->digits[i] = d % 10;
carry = d / 10;
}
if (carry > 0)
{
a->digits[len] = carry;
len++;
}
a->length = len;
}
void mul(struct number *a, int b)
{
int carry = 0;
char *p = &(a->digits[0]);
char *endp = &(a->digits[0]) + a->length;
while(p != endp)
{
int d = carry + *p * b;
*p = d % 10;
carry = d / 10;
p++;
}
if (carry > 0)
{
*p = carry;
a->length++;
}
}
int judge(struct counter *ctr, struct number *b, struct number *table)
{
static struct number t;
static int i;
assign(b, 0);
for (i = 9; i >= ctr->offset; i--)
{
if (ctr->digits[i] > 0)
{
copy(&table[(i * (N + 1)) + ctr->digits[i]], &t);
add(b, &t);
}
}
static struct counter new_ctr;
memset(&new_ctr, 0, sizeof(new_ctr));
new_ctr.offset = 0;
char *p = b->digits;
char *endp = b->digits + b->length;
if (b->length != N) return 0;
while (p != endp)
{
new_ctr.digits[(int)*p]++;
p++;
}
for (i = 0; i < ctr->offset; i++)
{
if (new_ctr.digits[i] != 0) return 0;
}
for (i = ctr->offset + 1; i < 10; i++)
{
if (ctr->digits[i] != new_ctr.digits[i]) return 0;
}
return 1;
}
int iter(struct number *table)
{
struct counter ctr;
ctr.offset = 9;
int remain = 0;
ctr.digits[9] = N;
while (1){
if (remain == 0)
{
struct number sum;
if (judge(&ctr, &sum, table))
{
print(&sum);printf("\n");
}
if (ctr.digits[ctr.offset] > 0)
{
ctr.digits[ctr.offset]--;
remain++;
}
else
{
while (ctr.digits[ctr.offset] == 0) ctr.offset++;
}
}
else
{
if (ctr.offset > 0)
{
ctr.offset--;
ctr.digits[ctr.offset] = remain;
remain = 0;
}
else
{
if (ctr.offset == 0 && remain == N) return 0;
while (ctr.digits[ctr.offset] == 0) ctr.offset++;
ctr.digits[ctr.offset]--;
remain++;
}
}
}
return 0;
}
void init_table(struct number *table)
{
int i, j;
for (i = 0; i < 10; i++)
{
assign(&table[i * (N + 1)], 0);
assign(&table[i * (N + 1) + 1], i);
for (j = 0; j < N - 1; j++)
{
mul(&table[i * (N + 1) + 1], i);
}
for (j = 2; j <= N; j++)
{
copy(&table[i * (N + 1) + j - 1], &table[i * (N + 1) + j]);
add(&table[i * (N + 1) + j], &table[i * (N + 1) + 1]);
}
}
}
int main(int argc, const char *argv[])
{
struct number *table = (struct number *)malloc(sizeof(struct number) * ((N + 1) * 10));
struct timeval time1, time2;
gettimeofday(&time1, NULL);
init_table(table);
iter(table);
free(table);
gettimeofday(&time2, NULL);
printf("time:%lu:%lu\n", time2.tv_sec - time1.tv_sec, time2.tv_usec - time1.tv_usec);
return 0;
}