例题3-5 UVa1583
1.大量重复处理相同数据可以通过预先处理随后查表来优化。
2.通过取余和除模来提取数字都某一位。
#include<stdio.h> #include<string.h> int number[100100]; int main(void){ memset(number,0,sizeof(number)); for(int i=1;i<100009;i++){//通过枚举,避免重复操作,提高效率。 int tmp=i; int now=i; while(now>0){ tmp+=now%10;//通过取余和除模可以提取数字的每一个位数。 now/=10; } if(number[tmp]==0||i<number[tmp]) number[tmp]=i; } int n,q; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&q); printf("%d ",number[q]);//直接查表即可。 } }
例题3-6 UVa1584
1.字典序,从前往后遍历,发现不等立即比较大小然后返回结果即可。
2.从中间某位置遍历数组整体可以通过取余来实现。
#include<stdio.h> #include<string.h> char s[110]; int compare(char *s,int a,int b){//字典序,顾名思义就是像字典那样排序, int n=strlen(s); for(int i=0;i<n;i++){//故从第一个字符往后遍历, if(s[(a+i)%n]!=s[(b+i)%n])//一旦发现不相等的字符(~这种循环的处理可以通过以长度为模取余实现~), return s[(a+i)%n] < s[(b+i)%n];//就比较两个字符的大小,直接返回这个结果。 } return 0; } int main(void){ int t; scanf("%d",&t); for(int times=0;times<t;times++){ scanf("%s",s); int len=strlen(s); int less=0; for(int i=1;i<len;i++){//一共有字符串长度个可能取法, if(compare(s,i, less)) less=i;//挨个比较,就能得出最终的最小取法的起始点。 } for(int i=0;i<len;i++) putchar(s[(i+less)%len]);//输出即可(同样使用循环的取余方法)。 putchar(' '); } }