网址:CSUST练习5
A N! HDU 1042 N的阶乘,大数相乘,这里的N<=10000,故可以用数组不用字符串。
代码: 1546ms
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 int a[40000]; 5 int main() 6 { 7 int n,i,j; 8 while(~scanf("%d",&n)) 9 { 10 if(n==1 || n==0) //n=1,n=0时另外讨论 11 { 12 printf("1\n"); 13 continue; 14 } 15 a[0]=1; //[0]记录数组的长度 16 a[1]=1; 17 for(i=2;i<=n;i++) 18 { 19 int sum=0; //清零 20 for(j=1;j<=a[0];j++) 21 { 22 int temp=a[j]*i+sum; 23 sum=temp/10; 24 a[j]=temp%10; 25 } 26 while(sum) //sum>10 27 { 28 a[j]=sum%10; 29 a[0]=j; 30 sum/=10; 31 j++; 32 } 33 } 34 for(i=a[0];i>=1;i--) //反序输出 35 printf("%d",a[i]); 36 printf("\n"); 37 } 38 return 0; 39 }
左右各有200间房间,编号一边为奇数,一边为偶数,中间有一条走廊,走廊最多只能让一张桌子通过,问n组,分别从a搬到b,最少要花多少时间?
代码: 贪心 0MS
1 #include <stdio.h> 2 #include <iostream> 3 #include <string.h> 4 #include <algorithm> 5 using namespace std; 6 int main() 7 { 8 int T,a[205],x,y,n,i,j,sum; 9 scanf("%d",&T); 10 while(T--) 11 { 12 sum=0; 13 memset(a,0,sizeof(a)); //清零 14 scanf("%d",&n); 15 for(i=1;i<=n;i++) 16 { 17 scanf("%d%d",&x,&y); 18 x=(x+1)/2; //处理奇数偶数 19 y=(y+1)/2; 20 if(x>y) 21 swap(x,y); //交换x,y的值,有头文件algorithm 22 for(j=x;j<=y;j++) 23 a[j]++; //表示占用 24 } 25 for(i=1;i<=200;i++) 26 if(a[i]>sum) 27 sum=a[i]; //同时最多要用到的 28 printf("%d\n",sum*10); //*10,每次10min 29 } 30 return 0; 31 }
C 变形课 HDU 1181 给出若干个字符串,0结束输入。若一个字符串的最后一个字符和另一个字符串的首字符相同,这两个字符串就变成一个,若能找到一个字符串一b开始,以m结束,则输出"Yes.",否则输"No.”
方法 DFS 本来我也是用DFS,但是后来写着写着,感觉不对.....因为每找一个字符串都要从第一个开始......╭(╯^╰)╮......然后我就放弃了....... QAQ
代码: 15ms
1 #include <stdio.h> 2 #include <iostream> 3 #include <string.h> 4 using namespace std; 5 int map[100005]; 6 int k,len; 7 class A 8 { 9 public: 10 char x,y; 11 int l; 12 }a[100005]; 13 void dfs(int i) 14 { 15 if(a[i].y=='m') //尾字母为m,结束,k=1 16 { 17 k=1; 18 return ; 19 } 20 else 21 for(int j=1;j<len;j++) 22 { 23 if(map[j]!=0 || a[j].x!=a[i].y) //不等于或者被标记,跳过 24 continue; 25 map[j]=1; 26 dfs(j); 27 map[j]=0; //记得清零 28 } 29 } 30 int main() 31 { 32 char s[1000]; 33 int j; 34 while(~scanf("%s",s)) 35 { 36 memset(map,0,sizeof(map)); 37 len=1; 38 k=0; 39 while(s[0]!='0') 40 { 41 a[len].l=strlen(s); //长度 42 a[len].x=s[0]; //首字母 43 a[len].y=s[a[len].l-1]; //尾字母 44 len++; //字符串的个数 45 scanf("%s",s); 46 } 47 for(j=1;j<len;j++) 48 if(a[j].x=='b') //找到b开始的字符串 49 { 50 map[j]=1; //标记 51 dfs(j); 52 } 53 if(k) 54 printf("Yes.\n"); 55 else 56 printf("No.\n"); 57 } 58 return 0; 59 }
D Calculation 2 HDU 3501 给出一个数n,求比n小且不与n互质的数的和。
利用欧拉公式:初等数论与欧拉公式:
f(n)表示所有小于n,且与n互质的数的个数,n=p1^a1*p2^a2*p3^a3.......
f(n)=n(1-1/p1)(1-1/p2)(1-1/p3)........
所以可以求出num=n-1-f(n),即与n不互质的数的个数,又由:对于整数n,如果x(x<n)与n互质,那么(n-x)也与n是互质的;同理如果x(x<n)与n不互质,那么(n-x)也与n是不互质的。所以两个不互质的数是关于中间数a,a-x和a+x的和就是n,所以sum=num*n/2;
代码: 15ms 本来还写了个0ms的,但是一样的代码再交一次却变成了15ms
#include <stdio.h> #include <iostream> using namespace std; int oula(int n) { int ans=n,i; for(i=2;i*i<=n;i++) { if(n%i==0) { n=n/i; while(n%i==0) n=n/i; ans=ans/i*(i-1); //欧拉公式 } if(n==1) //没有因子了 break; } if(n!=1) ans=ans/n*(n-1); return ans; } int main() { int n; __int64 sum,num; while(~scanf("%d",&n)&&n) { num=n-1-oula(n); sum=num*n/2; if(sum>=0) sum=sum%1000000007; //取余 else sum=sum+1000000007; //防止溢出,否则会运行错误 printf("%I64d\n",sum); } return 0; }
E An easy problem HDU 2601 给出一个数n<10^10,有i*j+i+j=n,满足0<i<=j,问有多少组这样的i,j。暴力肯定超时╮(╯▽╰)╭
i*j+i+j=(i+1)*(j+1)-1 所以:(i+1)*(j+1)=n+1;有:
代码: 2125ms
1 #include <stdio.h> 2 #include <iostream> 3 using namespace std; 4 int main() 5 { 6 int sum,T; 7 __int64 n,i; 8 scanf("%d",&T); 9 while(T--) 10 { 11 scanf("%I64d",&n); 12 sum=0; 13 for(i=1;(i+1)*(i+1)-1<=n;i++) //这样基本上就是从1~n^1/2了,而且是一重循环 14 { 15 if((n+1)%(i+1)==0) //(n+1)/(i+1)=(j+1),如果(n+1)%(i+1)==0,则这样的j存在 16 sum++; 17 } 18 printf("%d\n",sum); 19 } 20 return 0; 21 }