|
|
摘要:比较好的数论d(6543) = d(6 + 5 + 4 + 3) = d(18) = 9、其实d(n)=n%9all+=a[i]*a[j]*a[(i*j)%9];//是统计(i*j))%9==((k)%9)的次数 __int64 add=0; for(i=1;i<=n;i++) { for(j=i;j<=n;j+=i) { add++; } }//统计((i*j)%9==((k)%9))&&(i*j)==k的次数先减一下就是((i*j)%9==((k)%9))&&(i*j)!=k的次数View Code #include<stdio.h>
阅读全文
摘要:先暴力统计开始时逆序数对数量add再枚举a[i]add=add+(n-1)-2*a[i];记录最小View Code #include<stdio.h>int a[60009];int main(){int n;while(scanf("%d",&n)!=EOF){int i;for(i=1;i<=n;i++){scanf("%d",&a[i]);}int j;int add=0;for(i=1;i<n;i++){for(j=i+1;j<=n;j++){if(a[i]>a[j])add++;}}int
阅读全文
摘要:题目的具体做法是参考刘汝佳的《算法艺术与信息学奥赛》,代码倒是自己实现的。大概思路是:1.找出初始状态和目标状态。明显,目标状态就是排序后的状态。2.画出置换群,在里面找循环。例如,数字是8 4 5 3 2 7明显,目标状态是2 3 4 5 7 8,能写为两个循环:(8 2 7)(4 3 5)。3.观察其中一个循环,明显地,要使交换代价最小,应该用循环里面最小的数字2,去与另外的两个数字,7与8交换。这样交换的代价是:sum - min + (len - 1) * min化简后为:sum + (len - 2) * min其中,sum为这个循环所有数字的和,len为长度,min为这个环里面最小
阅读全文
摘要:View Code #include<stdio.h>#include<math.h>__int64 gcd(int a,int b){ if(b==0)return a; else gcd(b,a%b);}int main(){ int c,n; while(scanf("%d%d",&c,&n),c&&n) { __int64 add=0; int i; for(i=1;i<=n;i++) { add+=(__int64)pow(c*1.0,gcd(n,i)*1.0); } if(n&1) //翻转的
阅读全文
摘要:/*******************************************************************************************这里包含了rabinmiller素数测试与pollard算法求解最小质因数的方法,函数说明放到每个函数的前面*******************************************************************************************/不是自己写的学习一下View Code /*****************************************
阅读全文
摘要:View Code #include<stdio.h>#include<math.h>int prim(int p){ int t=(int)sqrt(1.0*p); int i; for(i=2;i<=t;i++) { if(p%i==0) return 0; } return 1;}int mon(int x,int exp,int p){ if(exp==0) return 1; __int64 ret=mon(x,exp>>1,p); ret=(ret*ret)%p; if(exp&1) { ret =(ret*x)%p; } retu
阅读全文
摘要:直接用欧几里得AX+BY=gcd(A,B);问题里s(n-m)+k*l=x-y所以存在s,k的整数解的话就要 (x-y)%gcd(n-m,l)再分情况考虑n-m是否是正负 枚举k得出解View Code #include<stdio.h>__int64 gcd(__int64 m,__int64 n){ __int64 t; while(n!=0) { t=m%n; m=n; n=t; } return m;}int main(){ __int64 x,y,m,n,l; while(scanf("%I64d%I64d%I64d%I64d%I64d",&x
阅读全文
摘要:做规律题是可以先暴力找规律发现规律在11111之类的数附近修改暴力程序继续找做规律题一定要把规律找透再写View Code #include<stdio.h>int main(){ int k; scanf("%d",&k); if(k==1) { printf("8\n"); return 0; } int n=(k-1)%6; if(n==1||n==2||n==4||n==5) printf("1\n"); else if(n==0) printf("4\n"); else printf(
阅读全文
摘要:给出数Q,求出最小的自然数N使得N!的末尾恰有Q个0,无解输出"No solution"对于一个数n,求出它的末尾有几个0,只需看n之内的数的质因子5的个数,因为2的个数远多于5。所以可知道一个数末尾0的个数Q = n/5 + n/(5^2) + n/(5^3) + ...Q = N(5^k - 1) / [4*(5^k)],由此得N = 4Q * [(5^k)/(5^k-1)]还有就是注意0不是自然数!View Code #include<stdio.h>int fun(int n){ int add=0; while(n) { add+=n/5; n/=5;
阅读全文
摘要:View Code #include<stdio.h>int main(){ int x,y; double z; scanf("%d%d%lf",&x,&y,&z); double t=(y-x)*60; t=(t-z)*(t-z)*1.0/t/t; printf("%.7lf\n",1-t);}
阅读全文
摘要:f(n)实际就是n%9但要注意n==0实际是9View Code #include<stdio.h>int ab[1009];int main(){ int t; scanf("%d",&t); while(t--) { int n,i,a; __int64 b; scanf("%d",&n); for(i=0;i<n;i++) scanf("%d",&ab[i]); b=ab[n-1]%9; for(i=1;i<n;i++) { b=(b+1)*ab[n-1-i]%9; } if(b=
阅读全文
摘要:组合问题里比较常用的数列1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862……令h(1)=1,h(0)=1,catalan数满足递归式:h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (其中n>=2)另类递归式:h(n)=((4*n-2)/(n+1))*h(n-1);View Code #include<stdio.h>int main(){ int k; scanf("%d",&k); int i,j; __int64 all=1; for(i=1;i<=k;i
阅读全文
摘要:主要是筛选法求素数 筛选法时间O(log(n)*n)两个素数和是素数,那其中一个必然是2View Code #include<stdio.h>#include<math.h>bool prim[1000009];int f[20009];//f记录可行解int main(){ int n; scanf("%d",&n); int i,j; int t=(int)sqrt(n*1.0);//筛选法大概选择1000,000要500ms for(i=2;i<=t;i++) { for(j=2;j*i<=n;j++) { prim[i*j
阅读全文
摘要://这题主要求S//结论:S=(251^(n+1)-1)*(2^(3n+1)-1)/250//是两个等比数列和相乘////推理://2008=2^3*251//所以2008^N有3N个2和N个251//所有仅由2组成的因子有//2^02^12^2...2^(3N)//设集合C={2^0,2^1,2^2...,2^(3N)};//SUM(C)=2^(3n+1)-1//跟251组合产生的因子有//251^0*C//251^1*C//...//251^N*C//所有因子和为://S=(251^(n+1)-1))/250*(2^(3n+1)-1)//计算S%K://S很大,不能保存在普通的数据类型中,
阅读全文
摘要:如将50倍化为二进制110010对应32 16 8 4 2 1就是50是由32+16+2组成(加法)而推广到乘法里2^50=(2^32)*(2^16)*(2^2)=2^(32+16+2)View Code #include<stdio.h>int main(){ int n,m,k; scanf("%d%d%d",&n,&m,&k); int i,add=0,t,j; for(i=1;i<=n;i++) { __int64 all,rall=1; scanf("%d",&t); all=t; int co
阅读全文
摘要:1*2+2*3+3*4+……+n*(n+1)=n*(n+1)*(n+2)/3注意数据大了,所以先n*(n+1)取% (20090524*3)保证后面的数可以被3除View Code #include<stdio.h>int t;int main(){ scanf("%d",&t); while(t--) { __int64 n; scanf("%I64d",&n); __int64 all=0; if(n==1) { printf("1\n"); continue; } all=(__int64)(n*(n
阅读全文
摘要:先暴力下8位数前为零9位时位8那10就为8*9=72那11位就为8*10*9以此类推……View Code #include<stdio.h>int main(){ int n; scanf("%d",&n); if(n<=8) printf("0\n"); else if(n==9) printf("8\n"); else if(n==10) printf("72\n"); else { printf("72"); int i; for(i=11;i<=n;i+
阅读全文
摘要:View Code #include <stdio.h>int main(){ int year,month,day; while(scanf("%d%d%d",&year,&month,&day)!=EOF) { if ( month < 3 ) { year -= 1; month += 12; } char b[7][10] = {"sunday","monday","tuesday","wednesday","thursday"
阅读全文
摘要:先写个暴力的找找规律暴力:View Code看看1到18的数据有规律可循奇数到偶数时是原来的奇数累积的+奇数第几位/2偶数到奇数是(前面的奇数第几位/2)*前面的奇数第几位View Code #include<stdio.h>int main(){ int n; while(scanf("%d",&n)!=EOF) { int i,add=0,j=0; for(i=4;i<=n;i++) { if(i%2==0) { j++; add+=j; } else { add+=j*(i-2); } } printf("%d\n",ad
阅读全文
摘要:注意精度高点没错的View Code #include<stdio.h>#include<math.h>#define R 6378.00#define PI 3.1415926535#define hu 360/3.1415926535/2int main(){ int t; double x1,y1,z1,x2,y2,z2,th1,th2,a1,a2,dis,q; scanf("%d",&t); while(t--) { double a=sin(30/hu); scanf("%lf%lf%lf%lf",&th
阅读全文
|