ZOJ 1133

Smith数的定义是各位数字之和与它的各个质因数(可以重复)的各位数字之和的总和相同的数,且不是素数

题目本身是一道水题,数据尤其水。

下面的代码中加了一个优化:

先将所有询问按询问的数字升序排序,处理某个询问A时,如果结果是B,那么对其后询问值小于B的所有询问,都直接

给出答案为B。

例如:

23

24

25

26

27

0

在处理23时得到58,由于后面四个数都小于58,于是后面四个询问直接得到答案58而不必重复劳动。

最后再将所有询问按原先次序排序即可。

这样总体的平均时间复杂度介于O(m)和O(mlogm)之间,m为询问个数。

以下为代码。

时间:10毫秒

#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "math.h"
int prime[1200];
int Smith[5];
struct query{
	int ask,pos,ans;
};
int cmp_by_ask(const void *a,const void *b){
	return (*(query *)a).ask-(*(query *)b).ask;
}
int cmp_by_pos(const void *a,const void *b){
	return (*(query *)a).pos-(*(query *)b).pos;
}
void getPrime(){
	memset(prime,0,sizeof(prime));
	int i,j,sq,flag;
	prime[1]=2;
	prime[2]=3;
	prime[3]=5;
	prime[4]=7;
	prime[0]=4;
	for(i=11;i<=10100;i++){
		if(!(i%2&&i%3&&i%5&&i%7))continue;
		sq=(int)(ceil(sqrt((double)i))+1);
		flag=1;
		for(j=11;j<=sq;j++){
			if(i%j==0){
				flag=0;
				break;
			}
		}
		if(flag){
			prime[0]++;
			prime[prime[0]]=i;
		}
	}
}
int getSum(int x){
	int sum=0;
	while(x){
		sum+=(x%10);
		x/=10;
	}
	return sum;
}
int is_Smith(int x){
	int sum1=0,sum2=getSum(x),i,j,cnt=0;
	for(i=1;i<=prime[0];i++){
		while(x%prime[i]==0){
			sum1+=getSum(prime[i]);
			cnt++;
			x/=prime[i];
		}
	}
	if(x!=1){
		sum1+=getSum(x);
		cnt++;
	}
	if((sum1==sum2)&&(cnt>1))return 1;
	else return 0;
}
int main(){
	query p[50000];
	int i,j,n,k,top;
	top=0;
	while(1){
		scanf("%d",&p[top].ask);
		if(p[top].ask==0)break;
		p[top].pos=top;
		p[top].ans=-1;
		top++;
	}
	qsort(p,top,sizeof(p[0]),cmp_by_ask);
	getPrime();
	//for(i=0;i<top;i++){
		//printf("%d ",p[i].ask);
	//}//
	//printf("\n");
	for(i=0;i<top;i++){
		//printf("I=%d.\n",i);
		j=p[i].ask+1;
		while(1){
			if(is_Smith(j)){
				p[i].ans=j;
				break;
			}
			else j++;
		}
		//printf("j=%d.\n",j);
		for(k=i+1;k<top;k++){
			//printf("k=%d.\n",k);
			if(p[k].ask<j){
				p[k].ans=j;
			}
			else break;
		}
		//printf("***k=%d.\n",k);
		i=k-1;
	}
	qsort(p,top,sizeof(p[0]),cmp_by_pos);
	for(i=0;i<top;i++){
		printf("%d\n",p[i].ans);
	}
	return 0;
}

ZOJ 1133,布布扣,bubuko.com

时间: 2024-10-10 09:34:16

ZOJ 1133的相关文章

zoj题目分类

饮水思源---zoj 转载自:http://bbs.sjtu.edu.cn/bbscon,board,ACMICPC,file,M.1084159773.A.html 注:所有不是太难的题都被归成了“简单题”,等到发现的时候已经太晚了,我太死脑筋 了……:( 有些题的程序我找不到了,555……:( SRbGa的题虽然都很经典……但是由于其中的大部分都是我看了oibh上的解题报告后做 的,所以就不写了…… 题目排列顺序没有规律……:( 按照个人感觉,最短路有的算做了DP,有的算做了图论. 有些比较

概率dp ZOJ 3640

Help Me Escape Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Practice ZOJ 3640 Appoint description:  System Crawler  (2014-10-22) Description Background     If thou doest well, shalt thou not be accepted? an

zoj 2156 - Charlie&#39;s Change

题目:钱数拼凑,面值为1,5,10,25,求组成n面值的最大钱币数. 分析:dp,01背包.需要进行二进制拆分,否则TLE,利用数组记录每种硬币的个数,方便更新. 写了一个 多重背包的 O(NV)反而没有拆分快.囧,最后利用了状态压缩优化 90ms: 把 1 cents 的最后处理,其他都除以5,状态就少了5倍了. 说明:貌似我的比大黄的快.(2011-09-26 12:49). #include <stdio.h> #include <stdlib.h> #include <

ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 最小生成树 Kruskal算法

题目链接:ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 Building a Space Station Time Limit: 2 Seconds      Memory Limit: 65536 KB You are a member of the space station engineering team, and are assigned a task in the construction process of the statio

ZOJ 3607 Lazier Salesgirl (贪心)

Lazier Salesgirl Time Limit: 2 Seconds      Memory Limit: 65536 KB Kochiya Sanae is a lazy girl who makes and sells bread. She is an expert at bread making and selling. She can sell the i-th customer a piece of bread for price pi. But she is so lazy

ZOJ - 2243 - Binary Search Heap Construction

先上题目: Binary Search Heap Construction Time Limit: 5 Seconds      Memory Limit: 32768 KB Read the statement of problem G for the definitions concerning trees. In the following we define the basic terminology of heaps. A heap is a tree whose internal n

ZOJ 2859 二维线段树

思路:自己写的第二发二维线段树1A,哈哈,看来对二维的push操作比较了解了:但是还没遇到在两个线段树中同时进行push操作的,其实这题我是想在x维和y维同时进行push操作的,但是想了好久不会,然后看到这题又给出10秒,然后想想在x维线段直接单点查询肯定也过了,然后在第二维就只有pushup操作,在第一维线段树没有pushup操作.要是在第一维也有pushup操作的话,那就不用单点查询那么慢了.不过也A了,想找题即在二维同时进行pushup和pushdown操作的. #include<iost

ZOJ 2588

求一个无向图的桥(可能存在重边),输出割边的数目,并按顺序输出割边的序号(输入的顺序). 由于内存的限制 , 无法使用邻接矩阵 , 只能用邻接表了 . 第一次用了邻接表,超内存了: 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <string.h> 5 using namespace std; 6 const int N=10002; 7 const i

ZOJ 2587 Unique Attack 判断最小割是否唯一

很裸的判断最小割是否唯一.判断方法是先做一遍最大流求最小割,然后从源点和汇点分别遍历所有能够到达的点,看是否覆盖了所有的点,如果覆盖了所有的点,那就是唯一的,否则就是不唯一的. #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostr